(8720,18673,'2015-12-03 19:31:32','2015-12-03 19:31:32','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types-300x53.png\" alt=\"Different types of markers in Forge.\" width=\"300\" height=\"53\" class=\"aligncenter size-medium wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:31:32','2015-12-03 19:31:32','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8721,18673,'2015-12-03 19:49:06','2015-12-03 19:49:06','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:49:06','2015-12-03 19:49:06','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8722,18673,'2015-12-03 19:49:54','2015-12-03 19:49:54','<title>Forge Visualizations!</title>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:49:54','2015-12-03 19:49:54','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8723,18673,'2015-12-03 19:50:15','2015-12-03 19:50:15','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:50:15','2015-12-03 19:50:15','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8724,18673,'2015-12-03 19:54:59','2015-12-03 19:54:59','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><code>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</code></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:54:59','2015-12-03 19:54:59','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8725,18673,'2015-12-03 19:55:43','2015-12-03 19:55:43','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:55:43','2015-12-03 19:55:43','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8726,18673,'2015-12-03 19:56:19','2015-12-03 19:56:19','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<p><code>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</code></p>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:56:19','2015-12-03 19:56:19','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8727,18673,'2015-12-03 19:59:52','2015-12-03 19:59:52','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<p><code><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></code></p>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<p><code><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></code></p>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<p><code><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<p><code><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></code></p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<p><code><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<p><code><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</code></p>\r\n<p><code><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</code></p>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:59:52','2015-12-03 19:59:52','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8728,18673,'2015-12-03 20:02:26','2015-12-03 20:02:26','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<p><code><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></code></p>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<p><code><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT,\r\n    const char * const title = NULL);</strong></code></p>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<p><code><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<p><code><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></code></p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<p><code><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<p><code><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</code></p>\r\n<p><code><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</code></p>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 20:02:26','2015-12-03 20:02:26','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8729,18673,'2015-12-03 20:03:46','2015-12-03 20:03:46','<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" class=\"aligncenter size-medium wp-image-8714\" /></a>\r\nThe plot function has the signature:</p>\r\n<p><code><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></code></p>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" class=\"aligncenter size-medium wp-image-8707\" /></a></p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The af::Window::scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" class=\"aligncenter size-medium wp-image-8715\" /></a></p>\r\n<p>The scatter function has the signature:</p>\r\n<p><code><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></code></p>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<p><code><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" class=\"aligncenter size-medium wp-image-8716\" /></a></p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<p><code><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></code></p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" class=\"aligncenter size-medium wp-image-8711\" /></a></p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The af::Window::scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<p><code><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></code></p>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" class=\"aligncenter size-medium wp-image-8712\" /></a></p>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" class=\"aligncenter size-full wp-image-8709\" /></a></p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" class=\"aligncenter size-medium wp-image-8713\" /></a>\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<p><code><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</code></p>\r\n<p><code><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</code></p>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.</p>','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 20:03:46','2015-12-03 20:03:46','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8735,18673,'2016-05-19 10:00:02','2016-05-19 14:00:02','Programmers and Data Scientists want to take advantage of fast and parallel computational devices. One of the best ways of doing this is to write vectorized code; however, this is often easier said than done. In today\'s continuation of the blog series \"<a href=\"http://sandbox.arrayfire.com/tag/learning-arrayfire-from-scratch/\">Learning ArrayFire from scratch</a>\", we will discuss the various methods by which you can maximize the performance of your code by using ArrayFire\'s built-in vectorization features.\r\n\r\n<!--more-->\r\n\r\nArrayFire provides many ways to vectorize a given code segment. In this tutorial, we present several methods to vectorize code using ArrayFire and discuss the benefits and drawbacks associated with each method.\r\n<h4><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h4>\r\nBy its very nature, ArrayFire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example consider the following code:\r\n<pre class=\"lang:default decode:true \">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}</pre>\r\nAlthough completely valid, the code is very inefficient as it results in a kernel that operate on one datum. Instead, the developer should have used ArrayFire\'s overload of the + operator:\r\n<pre><code class=\"language-{.cpp}\">\r\naf::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\nThis code will result in a single kernel that operates on all 10 elements of <code>a</code> in parallel.\r\n\r\nMost ArrayFire functions are vectorized. A small subset of these include:\r\n\r\n<strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n\r\nIn addition to element-wise operations, many other functions are also vectorized in ArrayFire.\r\n\r\nNotice that even that performs some form of aggregation (e.g. <code>sum()</code> or <code>min()</code>), signal processing (like <code>convolve()</code>), and even image processing functions (i.e. <code>rotate()</code>) all support vectorization on different columns or images. For example, if we have <code>NUM</code> images of size <code>WIDTH</code> by <code>HEIGHT</code>, one could convolve each image in a vector fashion as follows:\r\n<pre class=\"lang:default decode:true \">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);</pre>\r\nSimilarly, one can rotate 100 images by 45 degrees in a single call using code like the following:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">// Construct an array of 100 WIDTH x HEIGHT images of random numbers\r\naf::array imgs = randu(WIDTH, HEIGHT, 100);\r\n// Rotate all of the images in a single command\r\naf::array rot_imgs = rotate(imgs, 45);</pre>\r\n</div>\r\n</div>\r\nAlthough <em>most</em> functions in ArrayFire do support vectorization, some do not. Most notably, all linear algebra functions. Even though they are not vectorized linear algebra operations still execute in parallel on your hardware.\r\n\r\nUsing the built in vectorized operations should be the first and preferred method of vectorizing any code written with ArrayFire.\r\n<h4><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h4>\r\nAnother novel method of vectorization present in ArrayFire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire\'s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.\r\n\r\nThe original for-loop example at the beginning of this document could be rewritten using GFOR as follows:\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\nIn this case, each instance of the gfor loop is independent, thus ArrayFire will automatically tile out the <code>a</code> array in device memory and execute the increment kernels in parallel.\r\n\r\nTo see another example, you could run an <a class=\"el\" title=\"C++ Interface exclusive sum (cumulative sum) of an array. \" href=\"http://arrayfire.org/docs/group__scan__func__accum.htm\">accum()</a> on every slice of a matrix in a for-loop, or you could \"vectorize\" and simply do it all in one gfor-loop operation:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">// runs each accum() in sequence\r\nfor (int i = 0; i &lt; N; ++i)\r\n    B(span,i) = accum(A(span,i));\r\n \r\n// runs N accums in parallel\r\ngfor (seq i, N)\r\n    B(span,i) = accum(A(span,i));</pre>\r\n</div>\r\n</div>\r\nHowever, returning to our previous vectorization technique, <a class=\"el\" title=\"C++ Interface exclusive sum (cumulative sum) of an array. \" href=\"http://arrayfire.org/docs/group__scan__func__accum.htm\">accum()</a> is already vectorized and the operation could be completely replaced with merely:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">B = accum(A);</pre>\r\n</div>\r\n</div>\r\nIt is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n \r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);</pre>\r\n</div>\r\n</div>\r\nUsing GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the <a class=\"el\" href=\"http://arrayfire.org/docs/page_gfor.htm\">GFOR documentation</a>.\r\n<h4><a id=\"Batching_127\"></a>Batching</h4>\r\nThe <a class=\"el\" href=\"http://arrayfire.org/docs/namespaceaf.htm#aa0eb9e160f5be4b95234543e5c47934b\">batchFunc()</a> function allows the broad application of existing ArrayFire functions to multiple sets of data. Effectively,<a class=\"el\" href=\"http://arrayfire.org/docs/namespaceaf.htm#aa0eb9e160f5be4b95234543e5c47934b\">batchFunc()</a> allows ArrayFire functions to execute in \"batch processing\" mode. In this mode, functions will find a dimension which contains \"batches\" of data to be processed and will parallelize the procedure.\r\n\r\nConsider the following example. Here we create a filter which we would like to apply to each of the weight vectors. The naive solution would be using a for-loop as we have seen previously:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">// Create the filter and the weight vectors\r\naf::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n \r\n// Apply the filter using a for-loop\r\naf::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i&lt;weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}</pre>\r\n</div>\r\n</div>\r\nHowever, as we have discussed above, this solution will be very inefficient. One may be tempted to implement a vectorized solution as follows:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">// Create the filter and the weight vectors\r\naf::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n \r\naf::array filtered_weights = filter * weights; // fails due to dimension mismatch</pre>\r\n</div>\r\n</div>\r\nHowever, the dimensions of <code>filter</code> and <code>weights</code> do not match, thus ArrayFire will generate a runtime error.\r\n\r\n<code>batchfunc()</code> was created to solve this specific problem. The signature of the function is as follows:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</pre>\r\n</div>\r\n</div>\r\nwhere <code>batchFunc_t</code> is a function pointer of the form:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</pre>\r\n</div>\r\n</div>\r\nSo, to use <a class=\"el\" href=\"http://arrayfire.org/docs/namespaceaf.htm#aa0eb9e160f5be4b95234543e5c47934b\">batchFunc()</a>, we need to provide the function we wish to apply as a batch operation. For illustration\'s sake, let\'s \"implement\" a multiplication function following the format.\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\nreturn lhs * rhs;\r\n}</pre>\r\n</div>\r\n</div>\r\nOur final batch call is not much more difficult than the ideal syntax we imagined.\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">// Create the filter and the weight vectors\r\naf::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n \r\n// Apply the batch function\r\naf::array filtered_weights = batchFunc( filter, weights, my_mult );</pre>\r\n</div>\r\n</div>\r\nThe batch function will work with many previously mentioned vectorized ArrayFire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <code>__batchFunc_t__</code> signature. One limitation of <code>batchfunc()</code> is that it cannot be used from within a <code><a class=\"el\" href=\"http://arrayfire.org/docs/gfor_8h.htm#a6d6cd11d53daad217fd0b92f5a7ceec6\">gfor()</a></code> loop at the present time.\r\n<h4><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h4>\r\nWe have seen the different methods ArrayFire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:\r\n\r\n<a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a>\r\n\r\nIt’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that ArrayFire doesn’t already have an implementation. The default vectorized nature of ArrayFire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!','Introduction to Vectorization in ArrayFire','','publish','open','closed','','introduction-to-vectorization','','','2017-08-07 02:38:19','2017-08-07 06:38:19','',0,'http://sandbox.arrayfire.com/?p=8735',0,'post','',0),(8736,18673,'2015-12-03 20:56:43','2015-12-03 20:56:43','<title>introduction_to_vectorization.md</title>\r\n<p>Introduction to Vectorization</p>\r\n<p>Programmers and Data Scientists want to take advantage of fast and parallel\r\ncomputational devices. Writing vectorized code is becoming a necessity to get\r\nthe best performance out of the current generation parallel hardware and\r\nscientific computing software. However, writing vectorized code may not be\r\nintuitive immediately. Arrayfire provides many ways to vectorize a given code\r\nsegment. In this tutorial, we will be presenting various ways to vectorize code\r\nusing ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h1><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h1>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on\r\narrays as a whole – on all elements in parallel. Wherever possible, existing\r\nvectorized functions should be used opposed to manually indexing into arrays.\r\nFor example, consider this valid, yet mislead code that attempts to increment\r\neach element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>); <span class=\"hljs-comment\">// [0,  9]</span>\r\n<span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i = <span class=\"hljs-number\">0</span>; i &lt; a.dims(<span class=\"hljs-number\">0</span>); ++i)\r\n{\r\n    a(i) = a(i) + <span class=\"hljs-number\">1</span>;         <span class=\"hljs-comment\">// [1, 10]</span>\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>);  <span class=\"hljs-comment\">// [0,  9]</span>\r\na = a + <span class=\"hljs-number\">1</span>;                    <span class=\"hljs-comment\">// [1, 10]</span>\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;</p>\r\n<p><strong>Complex operations:</strong> real(), imag(), conj()…</p>\r\n<p><strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…</p>\r\n<p><strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…</p>\r\n<p><strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=</p>\r\n<p><strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…</p>\r\n<p><strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> arr = randn(<span class=\"hljs-number\">100</span>);\r\n<span class=\"hljs-built_in\">std</span>::<span class=\"hljs-built_in\">cout</span> &lt;&lt; min&lt;<span class=\"hljs-keyword\">float</span>&gt;(arr) &lt;&lt; <span class=\"hljs-built_in\">std</span>::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-keyword\">float</span> g_coef[] = { <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">1</span>,\r\n                   <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">4</span>, <span class=\"hljs-number\">2</span>,\r\n                   <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">1</span> };\r\n\r\naf::<span class=\"hljs-built_in\">array</span> filter = <span class=\"hljs-number\">1.f</span>/<span class=\"hljs-number\">16</span> * af::<span class=\"hljs-built_in\">array</span>(<span class=\"hljs-number\">3</span>, <span class=\"hljs-number\">3</span>, f_coef);\r\n\r\naf::<span class=\"hljs-built_in\">array</span> signal = randu(WIDTH, HEIGHT, NUM);\r\naf::<span class=\"hljs-built_in\">array</span> conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> imgs = randu(WIDTH, HEIGHT, <span class=\"hljs-number\">100</span>); <span class=\"hljs-comment\">// 100 (WIDTH x HEIGHT) images</span>\r\naf::<span class=\"hljs-built_in\">array</span> rot_imgs = rotate(imgs, <span class=\"hljs-number\">45</span>); <span class=\"hljs-comment\">// 100 rotated images</span>\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear\r\nalgebra functions. Using the built in vectorized operations should be the first\r\nand preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h1><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h1>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop\r\nreplacement construct. GFOR allows launching all iterations of a loop in parallel\r\non the GPU or device, as long as the iterations are independent. While the\r\nstandard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop\r\nperforms each iteration at the same time (in parallel). ArrayFire does this by\r\ntiling out the values of all loop iterations and then performing computation on\r\nthose tiles in one pass. You can think of gfor as performing auto-vectorization\r\nof your code, e.g. you write a gfor-loop that increments every element of a vector\r\nbut behind the scenes ArrayFire rewrites it to operate on the entire vector in\r\nparallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + <span class=\"hljs-number\">1</span>;\r\n</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a\r\nfor-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for <span class=\"hljs-comment\">(int i = 0; i &lt; N; ++i)</span>\r\n   B<span class=\"hljs-comment\">(span,i)</span> = accum<span class=\"hljs-comment\">(A(span,i)</span>); <span class=\"hljs-comment\">// runs each accum() in sequence</span>\r\ngfor <span class=\"hljs-comment\">(seq i, N)</span>\r\n   B<span class=\"hljs-comment\">(span,i)</span> = accum<span class=\"hljs-comment\">(A(span,i)</span>); <span class=\"hljs-comment\">// runs N accums in parallel</span>\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already\r\nvectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(<span class=\"hljs-keyword\">A</span>)<span class=\"hljs-comment\">;</span>\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in\r\nboth for-loops and gfor-loops. However, the gfor-loop construct is most effective\r\nin the narrow case of broadcast-style operations. Consider the case when we have\r\na vector of constants that we wish to apply to a collection of variables, such as\r\nexpressing the values of a linear combination for multiple vectors. The broadcast\r\nof one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-keyword\">const</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">int</span> p=<span class=\"hljs-number\">4</span>, n=<span class=\"hljs-number\">1000</span>;\r\naf::<span class=\"hljs-built_in\">array</span> consts = af::randu(p);\r\naf::<span class=\"hljs-built_in\">array</span> var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = <span class=\"hljs-function\">consts * <span class=\"hljs-title\">var_terms</span><span class=\"hljs-params\">(span, i)</span></span>;\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance.\r\nThe details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h1><a id=\"Batching_127\"></a>Batching</h1>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire\r\nfunctions to multiple sets of data. Effectively, batchFunc() allows Arrayfire\r\nfunctions to execute in “batch processing” mode. In this mode, functions will\r\nfind a dimension which contains “batches” of data to be processed and will\r\nparallelize the procedure.\r\nConsider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filter = randn(<span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">5</span>);\r\naf::<span class=\"hljs-built_in\">array</span> weights = randu(<span class=\"hljs-number\">5</span>, <span class=\"hljs-number\">5</span>);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors.\r\nThe naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filtered_weights = constant(<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">5</span>, <span class=\"hljs-number\">5</span>);\r\n<span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">0</span>; i&lt;weights.dims(<span class=\"hljs-number\">1</span>); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filtered_weights = filter * weights; <span class=\"hljs-comment\">// fails due to dimension mismatch</span>\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if\r\nArrayfire could figure out along which dimension we intend to apply the batch\r\noperation? That is exactly what <strong>batchFunc()</strong> does!\r\nThe signature of the function is:</p>\r\n<blockquote>\r\n<p>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</p>\r\n</blockquote>\r\n<p>where <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a\r\nbatch operation. For illustration’s sake, let’s “implement” a multiplication\r\nfunction following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-function\"><span class=\"hljs-built_in\">array</span> <span class=\"hljs-title\">my_mult</span> <span class=\"hljs-params\">(<span class=\"hljs-keyword\">const</span> af::<span class=\"hljs-built_in\">array</span> &amp;lhs, <span class=\"hljs-keyword\">const</span> af::<span class=\"hljs-built_in\">array</span> &amp;rhs)</span></span>{\r\n    <span class=\"hljs-keyword\">return</span> lhs * rhs;\r\n}\r\n</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal\r\nsyntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-rule\"><span class=\"hljs-attribute\">af</span>:<span class=\"hljs-value\">:array filtered_weights = <span class=\"hljs-function\">batchFunc</span>( filter, weights, my_mult )</span></span>;\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire\r\nfunctions. It can even work with a combination of those functions if they are\r\nwrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately,\r\nthe batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h1><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h1>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying\r\nthem all together is a slightly more involved process that needs to consider data\r\ndimensionality and layout, memory usage, nesting order, etc. An excellent example\r\nand discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the content discussed in the blog has since been transformed\r\ninto a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from\r\nscratch, check that Arrayfire doesn’t already have an implementation. The default\r\nvectorized nature of Arrayfire and an extensive collection of functions will\r\nspeed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 20:56:43','2015-12-03 20:56:43','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8737,18673,'2015-12-03 20:59:46','2015-12-03 20:59:46','<p>Programmers and Data Scientists want to take advantage of fast and parallel\r\ncomputational devices. Writing vectorized code is becoming a necessity to get\r\nthe best performance out of the current generation parallel hardware and\r\nscientific computing software. However, writing vectorized code may not be\r\nintuitive immediately. Arrayfire provides many ways to vectorize a given code\r\nsegment. In this tutorial, we will be presenting various ways to vectorize code\r\nusing ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on\r\narrays as a whole – on all elements in parallel. Wherever possible, existing\r\nvectorized functions should be used opposed to manually indexing into arrays.\r\nFor example, consider this valid, yet mislead code that attempts to increment\r\neach element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>); <span class=\"hljs-comment\">// [0,  9]</span>\r\n<span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i = <span class=\"hljs-number\">0</span>; i &lt; a.dims(<span class=\"hljs-number\">0</span>); ++i)\r\n{\r\n    a(i) = a(i) + <span class=\"hljs-number\">1</span>;         <span class=\"hljs-comment\">// [1, 10]</span>\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>);  <span class=\"hljs-comment\">// [0,  9]</span>\r\na = a + <span class=\"hljs-number\">1</span>;                    <span class=\"hljs-comment\">// [1, 10]</span>\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;</p>\r\n<p><strong>Complex operations:</strong> real(), imag(), conj()…</p>\r\n<p><strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…</p>\r\n<p><strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…</p>\r\n<p><strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=</p>\r\n<p><strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…</p>\r\n<p><strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> arr = randn(<span class=\"hljs-number\">100</span>);\r\n<span class=\"hljs-built_in\">std</span>::<span class=\"hljs-built_in\">cout</span> &lt;&lt; min&lt;<span class=\"hljs-keyword\">float</span>&gt;(arr) &lt;&lt; <span class=\"hljs-built_in\">std</span>::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-keyword\">float</span> g_coef[] = { <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">1</span>,\r\n                   <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">4</span>, <span class=\"hljs-number\">2</span>,\r\n                   <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">1</span> };\r\n\r\naf::<span class=\"hljs-built_in\">array</span> filter = <span class=\"hljs-number\">1.f</span>/<span class=\"hljs-number\">16</span> * af::<span class=\"hljs-built_in\">array</span>(<span class=\"hljs-number\">3</span>, <span class=\"hljs-number\">3</span>, f_coef);\r\n\r\naf::<span class=\"hljs-built_in\">array</span> signal = randu(WIDTH, HEIGHT, NUM);\r\naf::<span class=\"hljs-built_in\">array</span> conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> imgs = randu(WIDTH, HEIGHT, <span class=\"hljs-number\">100</span>); <span class=\"hljs-comment\">// 100 (WIDTH x HEIGHT) images</span>\r\naf::<span class=\"hljs-built_in\">array</span> rot_imgs = rotate(imgs, <span class=\"hljs-number\">45</span>); <span class=\"hljs-comment\">// 100 rotated images</span>\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear\r\nalgebra functions. Using the built in vectorized operations should be the first\r\nand preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop\r\nreplacement construct. GFOR allows launching all iterations of a loop in parallel\r\non the GPU or device, as long as the iterations are independent. While the\r\nstandard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop\r\nperforms each iteration at the same time (in parallel). ArrayFire does this by\r\ntiling out the values of all loop iterations and then performing computation on\r\nthose tiles in one pass. You can think of gfor as performing auto-vectorization\r\nof your code, e.g. you write a gfor-loop that increments every element of a vector\r\nbut behind the scenes ArrayFire rewrites it to operate on the entire vector in\r\nparallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> a = af::range(<span class=\"hljs-number\">10</span>);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + <span class=\"hljs-number\">1</span>;\r\n</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a\r\nfor-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for <span class=\"hljs-comment\">(int i = 0; i &lt; N; ++i)</span>\r\n   B<span class=\"hljs-comment\">(span,i)</span> = accum<span class=\"hljs-comment\">(A(span,i)</span>); <span class=\"hljs-comment\">// runs each accum() in sequence</span>\r\ngfor <span class=\"hljs-comment\">(seq i, N)</span>\r\n   B<span class=\"hljs-comment\">(span,i)</span> = accum<span class=\"hljs-comment\">(A(span,i)</span>); <span class=\"hljs-comment\">// runs N accums in parallel</span>\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already\r\nvectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(<span class=\"hljs-keyword\">A</span>)<span class=\"hljs-comment\">;</span>\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in\r\nboth for-loops and gfor-loops. However, the gfor-loop construct is most effective\r\nin the narrow case of broadcast-style operations. Consider the case when we have\r\na vector of constants that we wish to apply to a collection of variables, such as\r\nexpressing the values of a linear combination for multiple vectors. The broadcast\r\nof one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-keyword\">const</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">int</span> p=<span class=\"hljs-number\">4</span>, n=<span class=\"hljs-number\">1000</span>;\r\naf::<span class=\"hljs-built_in\">array</span> consts = af::randu(p);\r\naf::<span class=\"hljs-built_in\">array</span> var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = <span class=\"hljs-function\">consts * <span class=\"hljs-title\">var_terms</span><span class=\"hljs-params\">(span, i)</span></span>;\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance.\r\nThe details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire\r\nfunctions to multiple sets of data. Effectively, batchFunc() allows Arrayfire\r\nfunctions to execute in “batch processing” mode. In this mode, functions will\r\nfind a dimension which contains “batches” of data to be processed and will\r\nparallelize the procedure.\r\nConsider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filter = randn(<span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">5</span>);\r\naf::<span class=\"hljs-built_in\">array</span> weights = randu(<span class=\"hljs-number\">5</span>, <span class=\"hljs-number\">5</span>);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors.\r\nThe naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filtered_weights = constant(<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">5</span>, <span class=\"hljs-number\">5</span>);\r\n<span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">0</span>; i&lt;weights.dims(<span class=\"hljs-number\">1</span>); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">array</span> filtered_weights = filter * weights; <span class=\"hljs-comment\">// fails due to dimension mismatch</span>\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if\r\nArrayfire could figure out along which dimension we intend to apply the batch\r\noperation? That is exactly what <strong>batchFunc()</strong> does!\r\nThe signature of the function is:</p>\r\n<blockquote>\r\n<p>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</p>\r\n</blockquote>\r\n<p>where <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a\r\nbatch operation. For illustration’s sake, let’s “implement” a multiplication\r\nfunction following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-function\"><span class=\"hljs-built_in\">array</span> <span class=\"hljs-title\">my_mult</span> <span class=\"hljs-params\">(<span class=\"hljs-keyword\">const</span> af::<span class=\"hljs-built_in\">array</span> &amp;lhs, <span class=\"hljs-keyword\">const</span> af::<span class=\"hljs-built_in\">array</span> &amp;rhs)</span></span>{\r\n    <span class=\"hljs-keyword\">return</span> lhs * rhs;\r\n}\r\n</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal\r\nsyntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-rule\"><span class=\"hljs-attribute\">af</span>:<span class=\"hljs-value\">:array filtered_weights = <span class=\"hljs-function\">batchFunc</span>( filter, weights, my_mult )</span></span>;\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire\r\nfunctions. It can even work with a combination of those functions if they are\r\nwrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately,\r\nthe batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying\r\nthem all together is a slightly more involved process that needs to consider data\r\ndimensionality and layout, memory usage, nesting order, etc. An excellent example\r\nand discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the content discussed in the blog has since been transformed\r\ninto a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from\r\nscratch, check that Arrayfire doesn’t already have an implementation. The default\r\nvectorized nature of Arrayfire and an extensive collection of functions will\r\nspeed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 20:59:46','2015-12-03 20:59:46','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8738,18673,'2015-12-03 21:08:44','2015-12-03 21:08:44','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be\r\nintuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;</p>\r\n<p><strong>Complex operations:</strong> real(), imag(), conj()…</p>\r\n<p><strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…</p>\r\n<p><strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…</p>\r\n<p><strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=</p>\r\n<p><strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…</p>\r\n<p><strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear\r\nalgebra functions. Using the built in vectorized operations should be the first\r\nand preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop\r\nreplacement construct. GFOR allows launching all iterations of a loop in parallel\r\non the GPU or device, as long as the iterations are independent. While the\r\nstandard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop\r\nperforms each iteration at the same time (in parallel). ArrayFire does this by\r\ntiling out the values of all loop iterations and then performing computation on\r\nthose tiles in one pass. You can think of gfor as performing auto-vectorization\r\nof your code, e.g. you write a gfor-loop that increments every element of a vector\r\nbut behind the scenes ArrayFire rewrites it to operate on the entire vector in\r\nparallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a\r\nfor-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already\r\nvectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in\r\nboth for-loops and gfor-loops. However, the gfor-loop construct is most effective\r\nin the narrow case of broadcast-style operations. Consider the case when we have\r\na vector of constants that we wish to apply to a collection of variables, such as\r\nexpressing the values of a linear combination for multiple vectors. The broadcast\r\nof one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance.\r\nThe details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire\r\nfunctions to multiple sets of data. Effectively, batchFunc() allows Arrayfire\r\nfunctions to execute in “batch processing” mode. In this mode, functions will\r\nfind a dimension which contains “batches” of data to be processed and will\r\nparallelize the procedure.\r\nConsider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors.\r\nThe naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i&lt;weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if\r\nArrayfire could figure out along which dimension we intend to apply the batch\r\noperation? That is exactly what <strong>batchFunc()</strong> does!\r\nThe signature of the function is:</p>\r\n<p>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t<code><strong></strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a\r\nbatch operation. For illustration’s sake, let’s “implement” a multiplication\r\nfunction following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal\r\nsyntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire\r\nfunctions. It can even work with a combination of those functions if they are\r\nwrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately,\r\nthe batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying\r\nthem all together is a slightly more involved process that needs to consider data\r\ndimensionality and layout, memory usage, nesting order, etc. An excellent example\r\nand discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the content discussed in the blog has since been transformed\r\ninto a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from\r\nscratch, check that Arrayfire doesn’t already have an implementation. The default\r\nvectorized nature of Arrayfire and an extensive collection of functions will\r\nspeed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:08:44','2015-12-03 21:08:44','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8739,18673,'2015-12-03 21:13:37','2015-12-03 21:13:37','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;</p>\r\n<p><strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear\r\nalgebra functions. Using the built in vectorized operations should be the first\r\nand preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop\r\nreplacement construct. GFOR allows launching all iterations of a loop in parallel\r\non the GPU or device, as long as the iterations are independent. While the\r\nstandard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop\r\nperforms each iteration at the same time (in parallel). ArrayFire does this by\r\ntiling out the values of all loop iterations and then performing computation on\r\nthose tiles in one pass. You can think of gfor as performing auto-vectorization\r\nof your code, e.g. you write a gfor-loop that increments every element of a vector\r\nbut behind the scenes ArrayFire rewrites it to operate on the entire vector in\r\nparallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a\r\nfor-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already\r\nvectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in\r\nboth for-loops and gfor-loops. However, the gfor-loop construct is most effective\r\nin the narrow case of broadcast-style operations. Consider the case when we have\r\na vector of constants that we wish to apply to a collection of variables, such as\r\nexpressing the values of a linear combination for multiple vectors. The broadcast\r\nof one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance.\r\nThe details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire\r\nfunctions to multiple sets of data. Effectively, batchFunc() allows Arrayfire\r\nfunctions to execute in “batch processing” mode. In this mode, functions will\r\nfind a dimension which contains “batches” of data to be processed and will\r\nparallelize the procedure.\r\nConsider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors.\r\nThe naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i&lt;weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if\r\nArrayfire could figure out along which dimension we intend to apply the batch\r\noperation? That is exactly what <strong>batchFunc()</strong> does!\r\nThe signature of the function is:</p>\r\n<p>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t<code><strong></strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a\r\nbatch operation. For illustration’s sake, let’s “implement” a multiplication\r\nfunction following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal\r\nsyntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire\r\nfunctions. It can even work with a combination of those functions if they are\r\nwrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately,\r\nthe batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying\r\nthem all together is a slightly more involved process that needs to consider data\r\ndimensionality and layout, memory usage, nesting order, etc. An excellent example\r\nand discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the content discussed in the blog has since been transformed\r\ninto a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from\r\nscratch, check that Arrayfire doesn’t already have an implementation. The default\r\nvectorized nature of Arrayfire and an extensive collection of functions will\r\nspeed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:13:37','2015-12-03 21:13:37','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8740,18673,'2015-12-03 21:14:13','2015-12-03 21:14:13','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear\r\nalgebra functions. Using the built in vectorized operations should be the first\r\nand preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop\r\nreplacement construct. GFOR allows launching all iterations of a loop in parallel\r\non the GPU or device, as long as the iterations are independent. While the\r\nstandard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop\r\nperforms each iteration at the same time (in parallel). ArrayFire does this by\r\ntiling out the values of all loop iterations and then performing computation on\r\nthose tiles in one pass. You can think of gfor as performing auto-vectorization\r\nof your code, e.g. you write a gfor-loop that increments every element of a vector\r\nbut behind the scenes ArrayFire rewrites it to operate on the entire vector in\r\nparallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a\r\nfor-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already\r\nvectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in\r\nboth for-loops and gfor-loops. However, the gfor-loop construct is most effective\r\nin the narrow case of broadcast-style operations. Consider the case when we have\r\na vector of constants that we wish to apply to a collection of variables, such as\r\nexpressing the values of a linear combination for multiple vectors. The broadcast\r\nof one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance.\r\nThe details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire\r\nfunctions to multiple sets of data. Effectively, batchFunc() allows Arrayfire\r\nfunctions to execute in “batch processing” mode. In this mode, functions will\r\nfind a dimension which contains “batches” of data to be processed and will\r\nparallelize the procedure.\r\nConsider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors.\r\nThe naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i&lt;weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if\r\nArrayfire could figure out along which dimension we intend to apply the batch\r\noperation? That is exactly what <strong>batchFunc()</strong> does!\r\nThe signature of the function is:</p>\r\n<p>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t<code><strong></strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a\r\nbatch operation. For illustration’s sake, let’s “implement” a multiplication\r\nfunction following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal\r\nsyntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire\r\nfunctions. It can even work with a combination of those functions if they are\r\nwrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately,\r\nthe batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying\r\nthem all together is a slightly more involved process that needs to consider data\r\ndimensionality and layout, memory usage, nesting order, etc. An excellent example\r\nand discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the content discussed in the blog has since been transformed\r\ninto a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from\r\nscratch, check that Arrayfire doesn’t already have an implementation. The default\r\nvectorized nature of Arrayfire and an extensive collection of functions will\r\nspeed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:14:13','2015-12-03 21:14:13','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8741,18673,'2015-12-03 21:31:42','2015-12-03 21:31:42','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i&lt;weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:</p>\r\n<p><code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t<code><strong></strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:31:42','2015-12-03 21:31:42','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8742,18673,'2015-12-03 21:35:50','2015-12-03 21:35:50','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:</p>\r\n<p><code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp;lhs, const af::array &amp;rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:35:50','2015-12-03 21:35:50','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8743,18673,'2015-12-03 21:40:46','2015-12-03 21:40:46','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:40:46','2015-12-03 21:40:46','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8744,18673,'2015-12-03 21:43:30','2015-12-03 21:43:30','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code></p>\r\n<p>where <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code>\r\nSo, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:43:30','2015-12-03 21:43:30','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8745,18673,'2015-12-03 21:44:18','2015-12-03 21:44:18','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code>\r\nwhere <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:44:18','2015-12-03 21:44:18','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8746,18673,'2015-12-03 21:47:49','2015-12-03 21:47:49','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\naf::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code>\r\nwhere <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:47:49','2015-12-03 21:47:49','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8747,18673,'2015-12-03 21:49:40','2015-12-03 21:49:40','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; ims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\naf::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code>\r\nwhere <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:49:40','2015-12-03 21:49:40','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8748,18673,'2015-12-03 21:50:34','2015-12-03 21:50:34','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\naf::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the [GFOR documentation](\\ref gfor).</p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code>\r\nwhere <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 21:50:34','2015-12-03 21:50:34','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8762,18673,'2015-12-03 22:37:32','2015-12-03 22:37:32','<p>Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is becoming a necessity to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be intuitive immediately. Arrayfire provides many ways to vectorize a given code segment. In this tutorial, we will be presenting various ways to vectorize code using ArrayFire and the benefits and drawbacks associated with each method.</p>\r\n<h2><a id=\"GenericDefault_vectorization_10\"></a>Generic/Default vectorization</h2>\r\n<p>By its very nature, Arrayfire is a vectorized library. Most functions operate on arrays as a whole – on all elements in parallel. Wherever possible, existing vectorized functions should be used opposed to manually indexing into arrays. For example, consider this valid, yet mislead code that attempts to increment each element of an array:</p>\r\n<pre><code class=\"language-{.cpp}\">af::<span class=\"hljs-built_in\">af::array a = af::range(10); // [0,  9]\r\nfor(int i = 0; i &lt; a.dims(0); ++i)\r\n{\r\n    a(i) = a(i) + 1;         // [1, 10]\r\n}\r\n</code></pre>\r\n<p>Instead, the existing vectorized Arrayfire overload of the + operator should have been used:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\naf::array a = af::range(10);  // [0,  9]\r\na = a + 1;                    // [1, 10]\r\n</code></pre>\r\n<p>Most Arrayfire functions are vectorized. A small subset of these include:</p>\r\n<p><strong>Arithmetic operations:</strong> +, -, *, / , %, &gt;&gt;, &lt;&lt;\r\n<strong>Complex operations:</strong> real(), imag(), conj()…\r\n<strong>Exponential and logarithmic functions:</strong> exp(), log(), expm1(), log1p()…\r\n<strong>Hyperbolic functions:</strong> sinh(), cosh(), tanh()…\r\n<strong>Logical operations:</strong> &amp;&amp;, ||, &lt;, &gt;, ==, !=\r\n<strong>Numeric functions:</strong> abs(), floor(), round(), min(), max()…\r\n<strong>Trigonometric functions:</strong> sin(), cos(), tan()…</p>\r\n<p>Not only elementwise arithmetic operations are vectorized in Arrayfire.</p>\r\n<p>Vector operations such as <strong>min()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array arr = randn(100);\r\nstd::cout &lt;&lt; min(arr) &lt;&lt; std::endl;\r\n</code></pre>\r\n<p>Signal processing functions like <strong>convolve()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">float g_coef[] = { 1, 2, 1,\r\n                   2, 4, 2,\r\n                   1, 2, 1 };\r\n\r\naf::array filter = 1.f/16 * af::array(3, 3, f_coef);\r\n\r\naf::array signal = randu(WIDTH, HEIGHT, NUM);\r\naf::array conv = convolve2(signal, filter);\r\n</code></pre>\r\n<p>Image processing functions such as <strong>rotate()</strong> support vectorization:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array imgs = randu(WIDTH, HEIGHT, 100); // 100 (WIDTH x HEIGHT) images\r\naf::array rot_imgs = rotate(imgs, 45); // 100 rotated images\r\n</code></pre>\r\n<p>One class of functions that does not support vectorization is the set of linear algebra functions. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with Arrayfire.</p>\r\n<h2><a id=\"GFOR_Parallel_forloops_76\"></a>GFOR: Parallel for-loops</h2>\r\n<p>Another novel method of vectorization present in Arrayfire is the GFOR loop replacement construct. GFOR allows launching all iterations of a loop in parallel on the GPU or device, as long as the iterations are independent. While the standard for-loop performs each iteration sequentially, ArrayFire’s gfor-loop performs each iteration at the same time (in parallel). ArrayFire does this by tiling out the values of all loop iterations and then performing computation on those tiles in one pass. You can think of gfor as performing auto-vectorization of your code, e.g. you write a gfor-loop that increments every element of a vector but behind the scenes ArrayFire rewrites it to operate on the entire vector in parallel.</p>\r\n<p>We can remedy our first example with GFOR:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array a = af::range(10);\r\ngfor(seq i, n)\r\n    a(i) = a(i) + 1;</code></pre>\r\n<p>To see another example, you could run an <strong>accum()</strong> on every slice of a matrix in a for-loop, or you could “vectorize” and simply do it all in one gfor-loop operation:</p>\r\n<pre><code class=\"language-{.cpp}\">for (int i = 0; i &lt; N; ++i)\r\n   B(span,i) = accum(A(span,i)); // runs each accum() in sequence\r\ngfor (seq i, N)\r\n   B(span,i) = accum(A(span,i)); // runs N accums in parallel\r\n</code></pre>\r\n<p>However, returning to our previous vectorization technique, <strong>accum()</strong> is already vectorized and the operation could be completely replaced with merely:</p>\r\n<pre><code class=\"language-{.cpp}\">    B = accum(A);\r\n</code></pre>\r\n<p>It is best to vectorize computation as much as possible to avoid the overhead in both for-loops and gfor-loops. However, the gfor-loop construct is most effective in the narrow case of broadcast-style operations. Consider the case when we have a vector of constants that we wish to apply to a collection of variables, such as expressing the values of a linear combination for multiple vectors. The broadcast of one set of constants to many vectors works well with gfor-loops:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int p=4, n=1000;\r\naf::array consts = af::randu(p);\r\naf::array var_terms = randn(p, n);\r\n\r\ngfor(seq i, n)\r\n    combination(span, i) = consts * var_terms(span, i);\r\n</code></pre>\r\n<p>Using GFOR requires following several rules and multiple guidelines for optimal performance. The details of this vectorization method can be found in the <a href=\"http://www.sandbox.arrayfire.com/docs/page_gfor.htm\">GFOR documentation.</a></p>\r\n<h2><a id=\"Batching_127\"></a>Batching</h2>\r\n<p>The <strong>batchFunc()</strong> function allows the broad application of existing Arrayfire functions to multiple sets of data. Effectively, batchFunc() allows Arrayfire functions to execute in “batch processing” mode. In this mode, functions will find a dimension which contains “batches” of data to be processed and will parallelize the procedure. Consider the following example:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filter = randn(1, 5);\r\naf::array weights = randu(5, 5);\r\n</code></pre>\r\n<p>We have a filter that we would like to apply to each of several weights vectors. The naive solution would be using a loop as we’ve seen before:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = constant(0, 5, 5);\r\nfor(int i=0; i &lt; weights.dims(1); ++i){\r\n    filtered_weights.col(i) = filter * weights.col(i);\r\n}\r\n</code></pre>\r\n<p>However we would like a vectorized solution. The following syntax begs to be used:</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = filter * weights; // fails due to dimension mismatch\r\n</code></pre>\r\n<p>but it fails due to the (5x1), (5x5) dimension mismatch. Wouldn’t it be nice if Arrayfire could figure out along which dimension we intend to apply the batch operation? That is exactly what <strong>batchFunc()</strong> does! The signature of the function is:\r\n<code>array batchFunc(const array &amp;lhs, const array &amp;rhs, batchFunc_t func);</strong></code>\r\nwhere <strong>batchFunc_t</strong> is a function pointer of the form:\r\n<code>typedef array (*batchFunc_t) (const array &amp;lhs, const array &amp;rhs);</code></p>\r\n<p>So, to use <strong>batchFunc()</strong>, we need to provide the function we will be applying as a batch operation. For illustration’s sake, let’s “implement” a multiplication function following the format.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array my_mult (const af::array &amp; lhs, const af::array &amp; rhs){\r\n    return lhs * rhs;\r\n}</code></pre>\r\n<p>Our final batch call is not much more difficult than the ideal syntax we imagined.</p>\r\n<pre><code class=\"language-{.cpp}\">af::array filtered_weights = batchFunc( filter, weights, my_mult );\r\n</code></pre>\r\n<p>The batch function will work with many previously mentioned vectorized Arrayfire functions. It can even work with a combination of those functions if they are wrapped inside a helper function matching the <strong>batchFunc_t</strong> signature. Unfortunately, the batch function cannot be used within a gfor() construct at this moment.</p>\r\n<h2><a id=\"Advanced_Vectorization_181\"></a>Advanced Vectorization</h2>\r\n<p>We have seen the different methods Arrayfire provides to vectorize our code. Tying them all together is a slightly more involved process that needs to consider data dimensionality and layout, memory usage, nesting order, etc. An excellent example and discussion of these factors can be found in another blog post:</p>\r\n<p><a href=\"http://sandbox.arrayfire.com/how-to-write-vectorized-code/\">http://sandbox.arrayfire.com/how-to-write-vectorized-code/</a></p>\r\n<p>It’s worth noting that the whole implementation discussed in the blog has since been transformed into a convenient <strong>af::nearestNeighbour()</strong> function. Before writing something from scratch, check that Arrayfire doesn’t already have an implementation. The default vectorized nature of Arrayfire and an extensive collection of functions will speed things up in addition to replacing dozens of lines of code!</p>\r\n\r\n','Introduction to Vectorization','','inherit','open','closed','','8735-revision-v1','','','2015-12-03 22:37:32','2015-12-03 22:37:32','',8735,'http://sandbox.arrayfire.com/8735-revision-v1/',0,'revision','',0),(8763,18673,'2015-12-03 22:42:56','2015-12-03 22:42:56','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp;&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>,&nbsp;&nbsp;&nbsp;&nbsp; where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X\'X) * X\'                                \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code>X = constant(1, NSAMPLES, N_order, f32);\r\n X.col(1) *= particles.col(0);\r\n for(int i=2; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-1) * particles.col(0); //replace each column with one order higher column\r\n// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U;\r\ncholesky(U, matmul(X.T(), X), true); //cholesky on X\'X, true parameter for upper triangular portion\r\narray z = solve(U.T(), matmul(X.T(), particles.col(1)), AF_MAT_LOWER); //solve and specify the coefficients are lower triangular for optimized solution method\r\nb = solve(U, z, AF_MAT_UPPER); //solve and specify the coefficients are upper triangular</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found <a href=\"https://github.com/syurkevi/leastsquares_arrayfire_example\">here.</a>\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-12-03 22:42:56','2015-12-03 22:42:56','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8764,18528,'2015-12-04 15:30:03','2015-12-04 15:30:03','Under Windows and Mac the Intel GPU drivers include OpenCL support; however, on Linux OpenCL on Intel GPUs is implemented through an open source project called <a href=\"http://www.freedesktop.org/wiki/Software/Beignet/\">Beignet</a> (pronnounced like \"ben-yay\", a type of <a href=\"http://en.wikipedia.org/wiki/Beignet\">French pastry</a> akin to a what we would call a \"fritter\" in English). Below I have written a step-by-step guide on how you can get Beignet running on an Ubuntu 14.10 system which has an Intel 3rd, 4th, or 5th <a href=\"http://ark.intel.com/\">generation Intel processor</a>. Instructions for other variants of Linux will be similar, except for the commands to install the prerequisite packages.\r\n\r\nThere are several little caveats which need to be discussed up front. Foremost, the Beignet project supports the following hardware:\r\n<ul>\r\n	<li>3rd Generation Intel Core Processors</li>\r\n	<li>Intel “Bay Trail” platforms with Intel HD Graphics</li>\r\n	<li>4th Generation Intel Core Processors (requires a kernel patch be applied for shared memory!)</li>\r\n	<li>5th Generation Intel Core Processors \"Broadwell\".</li>\r\n</ul>\r\nThere are also a few noteworthy issues of which you should be aware:\r\n<ul>\r\n	<li>If your computer is running a Linux kernel in the 3.15 or 3.16 branch, you will need to disable some register whitelist functionality every time you reboot your system. This can be accomplished by running <code>echo 0 &gt; /sys/module/i915/parameters/enable_cmd_parser</code> as root.</li>\r\n	<li>4th Generation Intel Processors (i.e. i3/5/7-4xxx) require a kernel patch for shared/local memory to function.</li>\r\n	<li>There is no double precision support</li>\r\n	<li>OpenGL-OpenCL interop via <code>cl_khr_gl_sharing</code> is not supported</li>\r\n</ul>\r\nThere are additional release notes that can be found on the <a href=\"http://www.freedesktop.org/wiki/Software/Beignet/\">Beignet</a> project page.\r\n<h3>Installing prerequisites</h3>\r\n<pre><code>sudo apt-get install build-essential g++ cmake \r\nsudo apt-get install clang libclang-3.5-dev libclang-dev libclang1\r\nsudo apt-get install ocl-icd-opencl-dev ocl-icd-libopencl1</code></pre>\r\nNote, if you are on a Ubuntu 14.04 system, you should install <code>libclang-3.4-dev</code> instead, then run <code>update-alternatives</code> to point <code>llvm-link</code> and <code>llvm-as</code> to the correct version. The latter can be accomplished using the following commands:\r\n<pre><code>sudo update-alternatives --install /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-3.4 34\r\nsudo update-alternatives --install /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-3.4 34  \r\n</code></pre>\r\nIf you want to use the standard OpenCL ICD loader, you will also need to install these packages:\r\n<pre><code>sudo apt-get install opencl-headers ocl-icd-dev ocl-icd-libopencl1    \r\n</code></pre>\r\nI would also recomment you install the <code>clinfo</code> program so that you can verify that your installation is successful:\r\n<pre><code>sudo apt-get install clinfo    \r\n</code></pre>\r\n<h3>Check out and compile Beignet</h3>\r\n<pre><code>git clone git://anongit.freedesktop.org/beignet\r\ncd beignet\r\ngit checkout Release_v1.0.0\r\nmkdir build\r\ncd build\r\ncmake ..   \r\n</code></pre>\r\nNOTE: There may be newer releases of Beinget. To find releases type <span class=\"lang:default decode:true crayon-inline\">git branch -a </span>on the console and pick the highest release version number.\r\n\r\nDuring the CMake stage, ensure that the OCL ICD header file is installed, otherwise the library will not create an installable client driver. If everything went fine, go ahead and compile the source using\r\n<pre><code>make    \r\n</code></pre>\r\n(Note, you can do make -jN with N &gt; 1 to do a parallel build.)\r\nNext we verify that Beignet is functioning correctly on your hardware by running unit tests. These can be found in the <code>utest</code> folder. The unit tests require some enviornmental variables be set prior to invocation:\r\n<pre><code>cd utests\r\nsource setenv.sh\r\n./utest_run   \r\n</code></pre>\r\nIf a significant fraction of the unit tests fail and you have a 3.15 or 3.16 kernel, you need to disable register whitelisting using a command similar to the following:\r\n<pre><code>sudo su\r\necho 0 &gt; /sys/module/i915/parameters/enable_cmd_parser\r\nexit    \r\n</code></pre>\r\nand try re-running the tests. Please note that this change is not permanent and you will need to re-run it if you reboot your system. Alternatively, you could add this command to a startup script. The Beignet release notes mention there is a kernel patch to fix this issue which you could backport if you so desired.\r\n\r\nIf most of the tests pass, but those that involve local memory (~20-30 of the tests) fail, you will need to apply the <a href=\"#kernel-patch\">kernel patch</a> listed below.\r\n\r\nIf all was well, install Beignet to your system:\r\n<pre><code>sudo make install   \r\n</code></pre>\r\nYou can see a list of installed software in the <code>install_manifest.txt</code> file in the build directory.\r\n<h3>Verify Beignet is installed</h3>\r\nIn a terminal run the <code>clinfo</code> program. You should see something like this:\r\n<pre><code>$ clinfo\r\n...      \r\nPlatform Name:              Intel Gen OCL Driver\r\nNumber of devices:          1\r\nDevice Type:                CL_DEVICE_TYPE_GPU\r\n...\r\nName:                       Intel(R) HD Graphics Haswell GT2 Desktop\r\nVendor:                     Intel\r\nDevice OpenCL C version:    OpenCL C 1.2 beignet 0.9.1\r\nDriver version:             0.9.1\r\nProfile:                    FULL_PROFILE\r\nVersion:                    OpenCL 1.2 beignet 0.9.1\r\nExtensions:                 cl_khr_global_int32_base_atomics \r\n                            cl_khr_global_int32_extended_atomics \r\n                            cl_khr_local_int32_base_atomics \r\n                            cl_khr_local_int32_extended_atomics \r\n                            cl_khr_byte_addressable_store cl_khr_icd   \r\n</code></pre>\r\nTake note that the Intel OpenCL driver is loaded for a GPU device using <code>beignet</code>. This indicates the Installable Client Driver (ICD) is correctly installed. Also note the extensions listed.\r\n<h3>Applying the kernel patch to enable OpenCL shared local memory.</h3>\r\nIf you are using Beignet on a 4th generation Intel processor, you will need to apply a kernel patch to enable shared/local memory. This is a fairly lengthy process that will require at least 70 GB of hard disk space and perhaps an hour of compilation time if the build is executed in parallel.\r\n\r\nIn the next few paragraphs I\'ll walk you through how you can apply the kernel patch. I have based my instructions on the <a href=\"https://help.ubuntu.com/community/Kernel/Compile\">kernel compilation instructions for Ubuntu</a>. Instructions for other variants of Linux will be significantly different.\r\n\r\nInstall prerequisites:\r\n<pre><code>sudo apt-get build-dep linux-image-`uname -r`    \r\n</code></pre>\r\nMake a working directory for the kernel somewhere and download the source\r\n<pre><code>mkdir kernel\r\ncd kernel\r\napt-get source linux-image-`uname -r`    \r\n</code></pre>\r\nNext we see if we can automatically apply the patch. First download the patch:\r\n<pre><code>wget https://01.org/sites/default/files/disable-batchbuffer-security.patch    \r\n</code></pre>\r\nNow <code>cd</code> into the kernel directory:\r\n<pre><code>cd linux-3.16.0    \r\n</code></pre>\r\nCheck some details about the patch\r\n<pre><code>git apply --stat ../disable-batchbuffer-security.patch    \r\n</code></pre>\r\nTry automatically applying the patch:\r\n<pre><code>git apply --check ../disable-batchbuffer-security.patch    \r\n</code></pre>\r\nIf it automatically applies with no errors, just apply it:\r\n<pre><code>git apply ../disable-batchbuffer-security.patch    \r\n</code></pre>\r\nIf it did not work (as was the case on my system), the change is fairly simple. Open the <code>drivers/gpu/drm/i915/i915_gem_execbuffer.c</code> file in an editor:\r\n<pre><code>gedit drivers/gpu/drm/i915/i915_gem_execbuffer.c   \r\n</code></pre>\r\nIn the <code>i915_gem_do_execbuffer</code> function, find the following code:\r\n<pre><code>flags = 0;\r\nif (args-&gt;flags &amp; I915_EXEC_SECURE) {\r\n    if (!file-&gt;is_master || !capable(CAP_SYS_ADMIN))\r\n        return -EPERM;    \r\n</code></pre>\r\nAnd add the line <code>flags |= I915_DISPATCH_SECURE;</code> as follows:\r\n<pre><code>flags = 0;\r\nflags |= I915_DISPATCH_SECURE;\r\nif (args-&gt;flags &amp; I915_EXEC_SECURE) {\r\n    if (!file-&gt;is_master || !capable(CAP_SYS_ADMIN))\r\n        return -EPERM;  \r\n</code></pre>\r\nThis was inserted on line 998 for me. Save the file. Now we need to compile and install the modified kernel.\r\n\r\nNow we build the new kernel. Run the following commands from within the kernel source directory:\r\n<pre><code>fakeroot debian/rules clean\r\nDEB_BUILD_OPTIONS=parallel=8 fakeroot debian/rules binary-headers binary-generic    \r\n</code></pre>\r\nThis will build some Debian packages and place them in the directory <em>above</em> the kernel source root.\r\n\r\nAfter the kernel has compiled, install it:\r\n<pre><code>cd ../ (or go back into the kernel directory)\r\nsudo dpkg -i linux-headers-3.16.0-29-generic_3.16.0-29.54_amd64.deb \r\nsudo dpkg -i linux-image-3.16.0-29-generic_3.16.0-29.54_amd64.deb    \r\n</code></pre>\r\n(you might have to change the numeric kernel version to match what you compiled) Now add the kernel to the boot options:\r\n<pre><code>sudo update-grub\r\nsudo reboot    \r\n</code></pre>\r\nNow go back and re-run the Beignet unit test framework from above. With any luck everything will work fine.','OpenCL on Intel HD / Iris graphics on Linux','','inherit','open','closed','','7739-revision-v1','','','2015-12-04 15:30:03','2015-12-04 15:30:03','',7739,'http://sandbox.arrayfire.com/7739-revision-v1/',0,'revision','',0),(8765,11,'2015-12-07 15:09:18','2015-12-07 15:09:18','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\"]\r\n[custom_headline type=\"left\" level=\"h2\"]\r\nArrayFire Installers\r\n[/custom_headline]\r\n[custom_headline type=\"left\" level=\"h5\"]\r\nEach download contains both CUDA and OpenCL files.\r\n[/custom_headline]\r\n[gap size=\"4%\"]\r\n\r\n[column type=\"one-fourth\"][button  block=\"true\" onclick=\"&lt;!-- Google Code for ArrayFire Download (Windows) Conversion Page\r\nIn your html page, add the snippet and call\r\ngoog_report_conversion when someone clicks on the\r\nchosen link or button. --&gt;\r\n&lt;script type=\"text/javascript\"&gt;\r\n/* &lt;!&amp;#91;CDATA&amp;#91; */\r\ngoog_snippet_vars = function() {\r\nvar w = window;\r\nw.google_conversion_id = 1021026651;\r\nw.google_conversion_label = \"18VJCJjPql4Q28Lu5gM\";\r\nw.google_remarketing_only = false;\r\n}\r\n// DO NOT CHANGE THE CODE BELOW.\r\ngoog_report_conversion = function(url) {\r\ngoog_snippet_vars();\r\nwindow.google_conversion_format = \"3\";\r\nwindow.google_is_call = true;\r\nvar opt = new Object();\r\nopt.onload_callback = function() {\r\nif (typeof(url) != \'undefined\') {\r\nwindow.location = url;\r\n}\r\n}\r\nvar conv_handler = window&amp;#91;\'google_trackConversion\'&amp;#93;;\r\nif (typeof(conv_handler) == \'function\') {\r\nconv_handler(opt);\r\n}\r\n}\r\n/* &amp;#93;&amp;#93;&gt; */\r\n&lt;/script&gt;\r\n&lt;script type=\"text/javascript\"\r\nsrc=\"//www.googleadservices.com/pagead/conversion_async.js\"&gt;\r\n&lt;/script&gt;\" class=\"center-text\" type=\"flat\" shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/windows-installer\" size=\"regular\" ]Windows, v3.2.1\r\n(64-bit)[/button][/column] [column type=\"one-fourth\"][button block=\"true\" type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/linux-x86_64-installer\" size=\"regular\" ]Linux, v3.2.1\r\n(64-bit)[/button][/column][column type=\"one-fourth\"][button  block=\"true\" type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/osx-installer\" size=\"regular\" ]Mac OSX, v3.2.1\r\n(64-bit)[/button][/column] [column type=\"one-fourth\" last=\"true\"][button block=\"true\"  type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/linux-armv7l-installer\" size=\"regular\" ]Tegra K1 v3.2.1\r\n(32-bit)[/button][/column][gap size=\"9%\"]\r\n\r\nCheck out our GitHub repository to <a href=\"https://github.com/arrayfire/arrayfire\">build from the source</a>.\r\n\r\nLooking for an older installer? <a href=\"http://sandbox.arrayfire.com/installer_archive\">Try here</a>.[/content_band]\r\n<p style=\"text-align: left;\">[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\" bg_color=\"#f1f1f1\"][column type=\"one-half\"][gap size=\"8%\"]<img class=\"aligncenter wp-image-5156\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/mobile_Exported1-e1395437261846.png\" alt=\"mobile_Exported\" width=\"233\" height=\"311\" />[/column][column type=\"one-half\" last=\"true\"]\r\n[custom_headline type=\"left\" level=\"h2\"]\r\nGreat. What now?\r\n[/custom_headline]</p>\r\n<p style=\"text-align: left;\">[gap size=\"5%\"]</p>\r\n<p style=\"text-align: left;\">Welcome to ArrayFire! You\'ve got an awesome library there—learn more about its features and functions on <a href=\"http://www.sandbox.arrayfire.com/docs/index.htm\">our documentation</a>.</p>\r\n<p style=\"text-align: left;\">In addition to our <a href=\"https://groups.google.com/forum/#!forum/arrayfire-users\">ArrayFire user group</a> and <a href=\"http://sandbox.arrayfire.com/blog/\">our blog</a>, we offer a plethora of <a href=\"http://sandbox.arrayfire.com/support/\">support options</a> to fit your needs.</p>\r\n<p style=\"text-align: left;\">Got a job that needs closer attention? Hire us! Our engineers are acceleration wizards. Check out our <a href=\"http://sandbox.arrayfire.com/consulting/\">consulting offerings</a>, or set up a free <a href=\"http://meetme.so/arrayfire\">technical consultation</a> with us today![/column]</p>\r\n<p style=\"text-align: left;\">[/content_band]</p>\r\n<p style=\"text-align: center;\"></p>','Download','','inherit','open','closed','','5931-revision-v1','','','2015-12-07 15:09:18','2015-12-07 15:09:18','',5931,'http://sandbox.arrayfire.com/5931-revision-v1/',0,'revision','',0),(8769,17729,'2015-12-11 16:01:59','2015-12-11 16:01:59','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library: ArrayFire-Rust - Rust bindings for ArrayFire. We have been working on the wrapper and using it in daily production within the company for the last few months and now regard it stable enough for public distribution.\r\n<h4><a id=\"How_to_use_arrayfire_from_cratesio_2\"></a>How to use ArrayFire from <a href=\"http://crates.io\">crates.io</a></h4>\r\nTo use the rust bindings for ArrayFire from <strong><a href=\"http://crates.io\">crates.io</a></strong>, the following requirements are to be met first:\r\n<ol>\r\n	<li>Download and install ArrayFire binaries based on your operating system.</li>\r\n	<li>If you are on Linux or OSX, set the environment variable <code>AF_PATH</code> to point to ArrayFire installation root folder. (This is automatically set for you on Windows.)</li>\r\n	<li>Make sure you add the path to library files to your path environment variables.\r\n<ul>\r\n	<li>On Linux &amp; OSX: do <code>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib</code></li>\r\n	<li>On Windows: Add <code>%AF_PATH%\\lib</code> to your PATH environment variable.</li>\r\n</ul>\r\n</li>\r\n	<li>Run <code>cargo new --bin helloworld &amp;&amp; helloworld</code></li>\r\n	<li>Edit <code>Cargo.toml</code> to add the line <code>arrayfire = \"3.3.0\"</code> to the <code>[dependencies]</code> section.</li>\r\n	<li>Add the following sample rust code to your source file <code>helloworld/src/main.rs</code>.\r\n<pre><code class=\"language-rust\">\r\nextern crate arrayfire as af;\r\nuse af::*; // Ideally, you should use only names you are about to use, for example purposes * is fine.\r\n    \r\nfn main() {\r\n    let num_rows: u64 = 5;\r\n    let num_cols: u64 = 3;\r\n    let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);\r\n    println!(\"Create a 5-by-3 matrix of random floats on the GPU\");\r\n    let a = randu::<f32>(dims);\r\n    print(&a);\r\n}\r\n</code></pre>\r\n</li>\r\n	<li>Run <code>cargo run</code> and you should see output similar to the one below.\r\n<pre><code class=\"language-bash\">\r\nCreate a 5-by-3 matrix of random floats on the GPU\r\n[5 3 1 1]\r\n    0.7402     0.4464     0.7762\r\n    0.9210     0.6673     0.2948\r\n    0.0390     0.1099     0.7140\r\n    0.9690     0.4702     0.3585\r\n    0.9251     0.5132     0.6814\r\n</code></pre>\r\n</li>\r\n</ol>\r\n<h4><a id=\"Documentation_44\"></a>Documentation</h4>\r\nYou can find the documentation for all the functions and macros available in the crate over <a href=\"http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html\">here</a>. You can also look at the ArrayFire C/C++ API documentation <a href=\"http://sandbox.arrayfire.com/docs/group__func__categories.htm\">on ArrayFire.com</a> which categorizes ArrayFire functions into several specific domains.\r\n<h4><a id=\"Example_Project_47\"></a>Example Project</h4>\r\n<a href=\"https://github.com/jramapuram/hal\">hal</a> project is one of the initial adaptors of our rust wrapper for ArrayFire to enable use of GPUs from Rust via ArrayFire.\r\n<h4><a id=\"Credits_50\"></a>Credits</h4>\r\nWe would like to thank <a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a> for helping us in writing and reviewing the rust bindings. We would also like to thank the <a href=\"https://users.rust-lang.org/\" target=\"_blank\">users from rust community</a> who provided their invaluable feedback while working on the bindings for ArrayFire.\r\n\r\n&nbsp;','Rust wrapper for ArrayFire','','publish','open','closed','','rust-wrapper-for-arrayfire','','','2016-06-08 01:08:19','2016-06-08 05:08:19','',0,'http://sandbox.arrayfire.com/?p=8769',0,'post','',0),(8770,17729,'2015-12-10 22:41:51','2015-12-10 22:41:51','','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 22:41:51','2015-12-10 22:41:51','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8771,17729,'2015-12-10 22:56:51','2015-12-10 22:56:51','We have been working\r\n\r\n&nbsp;\r\n\r\nAuthor Credits:\r\n\r\n[Jason Ramapuram](https://github.com/jramapuram)','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 22:56:51','2015-12-10 22:56:51','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8772,17729,'2015-12-10 23:08:47','2015-12-10 23:08:47','My journey with <a href=\"https://www.rust-lang.org/\" target=\"_blank\">Rust</a> started off by learning the basics of the language using the tutorials(<a href=\"https://doc.rust-lang.org/stable/book/guessing-game.html\" target=\"_blank\">Guessing Game</a> &amp; <a href=\"http://Dining Philosophers\" target=\"_blank\">Dining Philosophers</a>) available on the rust website. They are quite good to kick off the rusty ride.\r\n\r\n&nbsp;\r\n\r\nAuthor Credits:\r\n\r\n<a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a>','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:08:47','2015-12-10 23:08:47','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8773,17729,'2015-12-10 23:48:27','2015-12-10 23:48:27','In this post, we would be talking about our latest &amp; newest language bindings for ArrayFire library, ArrayFire-Rust - Rust bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\nAuthor Credits:\r\n\r\n<a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a>','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:48:27','2015-12-10 23:48:27','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8774,17729,'2015-12-10 23:49:11','2015-12-10 23:49:11','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library, ArrayFire-Rust - Rust bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\nAuthor Credits:\r\n\r\n<a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a>','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:49:11','2015-12-10 23:49:11','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8775,17729,'2015-12-10 23:55:37','2015-12-10 23:55:37','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library, <a href=\"https://github.com/arrayfire/arrayfire-rust\" target=\"_blank\">ArrayFire-Rust</a> - Rust bindings for ArrayFire. The wrapper itself has been a work in progress for the past few months and we think now it is ready for it\'s first release. &lt;h4&gt;Credits&lt;/h4&gt;We would like to thank <a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a> for helping us in writing and reviewing the rust bindings. We would also like to thank you the users from <a href=\"https://users.rust-lang.org/\" target=\"_blank\">rust community</a> who provided their valuable feedback while coming with the bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:55:37','2015-12-10 23:55:37','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8776,17729,'2015-12-10 23:56:46','2015-12-10 23:56:46','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library, <a href=\"https://github.com/arrayfire/arrayfire-rust\" target=\"_blank\">ArrayFire-Rust</a> - Rust bindings for ArrayFire. The wrapper itself has been a work in progress for the past few months and we think now it is ready for it\'s first release. CreditsWe would like to thank <a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a> for helping us in writing and reviewing the rust bindings. We would also like to thank the users from <a href=\"https://users.rust-lang.org/\" target=\"_blank\">rust community</a> who provided their invaluable feedback while working on the bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:56:46','2015-12-10 23:56:46','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8777,17729,'2015-12-10 23:57:34','2015-12-10 23:57:34','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library, <a href=\"https://github.com/arrayfire/arrayfire-rust\" target=\"_blank\">ArrayFire-Rust</a> - Rust bindings for ArrayFire. The wrapper itself has been a work in progress for the past few months and we think now it is ready for it\'s first release.\r\n<h4>Credits</h4>\r\nWe would like to thank <a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a> for helping us in writing and reviewing the rust bindings. We would also like to thank the users from <a href=\"https://users.rust-lang.org/\" target=\"_blank\">rust community</a> who provided their invaluable feedback while working on the bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-10 23:57:34','2015-12-10 23:57:34','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0),(8778,17729,'2015-12-11 00:01:26','2015-12-11 00:01:26','In this post, we would like to introduce our latest &amp; newest language bindings for ArrayFire library, <a href=\"https://github.com/arrayfire/arrayfire-rust\" target=\"_blank\">ArrayFire-Rust</a> - Rust bindings for ArrayFire. The wrapper itself has been a work in progress for the past few months and we think now it is ready for it\'s first release.\r\n<h4>Use arrayfire from crates.io</h4>\r\nTo use the rust bindings for ArrayFire from crates.io, the following requirements are to be met first.\r\n<ol>\r\n	<li><a href=\"https://sandbox.arrayfire.com/download\">Download and install ArrayFire binaries</a> based on your operating system.</li>\r\n	<li>Set the evironment variable <code>AF_PATH</code> to point to ArrayFire installation root folder.</li>\r\n	<li>Make sure you add the path to library files to your path environment variables.\r\n<ul>\r\n	<li>On Linux &amp; OSX: do <code>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib</code></li>\r\n	<li>On Windows: Add <code>%AF_PATH%\\lib</code> to your PATH environment variable.</li>\r\n</ul>\r\n</li>\r\n	<li>Add <code>arrayfire = \"3.2.0\"</code> to the dependencies section of your project\'s Cargo.toml file.</li>\r\n</ol>\r\n<h4>Credits</h4>\r\nWe would like to thank <a href=\"https://github.com/jramapuram\" target=\"_blank\">Jason Ramapuram</a> for helping us in writing and reviewing the rust bindings. We would also like to thank the users from <a href=\"https://users.rust-lang.org/\" target=\"_blank\">rust community</a> who provided their invaluable feedback while working on the bindings for ArrayFire.\r\n\r\n&nbsp;\r\n\r\n&nbsp;','ArrayFire from Rust','','inherit','open','closed','','8769-revision-v1','','','2015-12-11 00:01:26','2015-12-11 00:01:26','',8769,'http://sandbox.arrayfire.com/8769-revision-v1/',0,'revision','',0);


INSERT INTO `wp_posts` VALUES (9187,17729,'2016-09-19 13:55:18','2016-09-19 17:55:18','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 13:55:18','2016-09-19 17:55:18','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9188,17729,'2016-09-19 14:06:19','2016-09-19 18:06:19','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples code base which you can find <a>here href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\"</a>. This example shows a static and dynamic vector fields in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\">here</a></p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:06:19','2016-09-19 18:06:19','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9189,17729,'2016-09-19 14:08:43','2016-09-19 18:08:43','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples code base which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector fields in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:08:43','2016-09-19 18:08:43','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9190,11,'2016-09-21 22:13:43','2016-09-22 02:13:43','In ArrayFire v3.4, we have added support for sparse matrices, which greatly reduce the memory footprint on GPUs and accelerated devices for many applications.\r\n\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Sparse Data Structure[/custom_headline]\r\n\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are much greater than the number of non-zero elements (i.e. the sparsity of the matrix is high). A sparse data structure is generally stored as 3 arrays:\r\n<ul>\r\n 	<li>A data or values array containing all the non-zero elements</li>\r\n 	<li>A vector for row indices (based on storage format)</li>\r\n 	<li>A vector for column indices (based on storage format)</li>\r\n</ul>\r\nThere are many ways to store sparse matrices, the most prominent of which are:\r\n<ul>\r\n 	<li><a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a> (CSR)</li>\r\n 	<li><a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a> (CSC)</li>\r\n 	<li><a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a> (COO)</li>\r\n</ul>\r\nArrayFire supports CSR and COO format, with support for CSC coming in future releases.\r\n\r\nA more detailed description of sparse matrices can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Sparse Arrays in ArrayFire[/custom_headline]\r\n\r\nIn ArrayFire, sparse arrays use the same user-facing object, af::array. This makes working with sparse arrays very seamless. We have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not. Although externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other metadata. These arrays, as well as other properties, can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\nIn v3.4, the following features are supported for sparse arrays:\r\n<ul>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n<ul>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a></li>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a></li>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a></li>\r\n 	<li>To create a sparse array from a host or device dense array, first create a dense af::array, and then pass it to create sparse af::array.</li>\r\n</ul>\r\n</li>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n<ul>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a></li>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a></li>\r\n</ul>\r\n</li>\r\n 	<li><a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">Sparse-Dense Matrix Multiplication (SPMM/SPMV)</a>\r\n<ul>\r\n 	<li>Sparse Matrix - Dense Matrix</li>\r\n 	<li>Sparse Matrix - Dense Vector</li>\r\n 	<li>Options for Sparse Matrix to be transposed</li>\r\n</ul>\r\n</li>\r\n</ul>\r\nThe Sparse-Dense Matrix Multiplication is implemented within the same <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a> function used for dense arrays.\r\n\r\nAs with all ArrayFire features, sparse support is available across all backends (CUDA, OpenCL, and CPU) and supported devices and architectures.\r\n\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Example[/custom_headline]\r\n\r\nIn this section, we showcase the difference in running a conjugate gradient solver with a dense array and a sparse array. The inputs are the same for each example. In the sparse case, the \"A\" matrix is converted to sparse.\r\n<pre class=\"\">\r\n#include <arrayfire.h>\r\n#include <iostream>\r\n\r\nusing namespace af;\r\n\r\nstatic size_t dimension = 16 * 1024;\r\nstatic const int maxIter = 10;\r\nstatic const int sparsityFactor = 7;\r\n\r\nstatic array A;\r\nstatic array spA;  // Sparse A\r\nstatic array x0;\r\nstatic array b;\r\n\r\nvoid setupInputs()\r\n{\r\n    // Generate a random input: A\r\n    array T = randu(dimension, dimension, f32);\r\n    // Create 0s in input.\r\n    // Anything that is no divisible by sparsityFactor will become 0.\r\n    A = floor(T * 1000);\r\n    A = A * ((A % sparsityFactor) == 0) / 1000;\r\n    // Make it positive definite\r\n    A = transpose(A) + A + A.dims(0)*identity(A.dims(0), A.dims(0), f32);\r\n\r\n    // Make A sparse as spA\r\n    spA = sparse(A);\r\n\r\n    // Generate x0: Random guess\r\n    x0 = randu(A.dims(0), f32);\r\n\r\n    //Generate b\r\n    b = matmul(A, x0);\r\n\r\n    std::cout << \"Sparsity of A = \"\r\n              << 100.f * (float)sparseGetNNZ(spA) / (float)spA.elements()\r\n              << std::endl;\r\n    std::cout << \"Memory Usage of A = \" <<  A.bytes() << \" bytes\" << std::endl;\r\n    std::cout << \"Memory Usage of spA = \"\r\n              << sparseGetValues(spA).bytes()\r\n               + sparseGetRowIdx(spA).bytes()\r\n               + sparseGetColIdx(spA).bytes()\r\n              << \" bytes\" << std::endl;\r\n}\r\n\r\nvoid conjugateGradient(const af::array in)\r\n{\r\n    array x = constant(0, b.dims(), f32);\r\n    array r = b - matmul(in, x);\r\n    array p = r;\r\n\r\n    for (int i = 0; i < maxIter; ++i) {\r\n        array Ap = matmul(in, p);\r\n        array alpha_num = dot(r, r);\r\n        array alpha_den = dot(p, Ap);\r\n        array alpha = alpha_num/alpha_den;\r\n        r = r - tile(alpha, Ap.dims())*Ap;\r\n        x = x + tile(alpha, Ap.dims())*p;\r\n        array beta_num = dot(r, r);\r\n        array beta = beta_num/alpha_num;\r\n        p = r + tile(beta, p.dims())*p;\r\n    }\r\n    array res = x0 - x;\r\n\r\n    std::cout << \"Final difference in solutions:\\n\";\r\n    af_print(dot(res, res));\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    af::info();\r\n    setupInputs();\r\n\r\n    std::cout << \"Verifying Dense Conjugate Gradient:\" << std::endl;\r\n    conjugateGradient(A);\r\n\r\n    std::cout << \"Verifying Sparse Conjugate Gradient:\" << std::endl;\r\n    conjugateGradient(spA);\r\n\r\n    return 0;\r\n}\r\n</pre>\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Performance and Memory Footprint[/custom_headline]\r\n\r\nUsing the CUDA backend on a Tesla K40c, the conjugate gradient function took 64.94ms for the dense matrix and 39.31ms for the sparse Matrix. That is almost a 2x speedup!\r\n\r\nWith a <code>sparsityFactor</code> of 7, the sparsity of A is about 26.38%. This means a tremendous amount of memory is conserved. For a floating point matrix of size 16M x 16M, a dense matrix uses 1 GB of memory while the sparse array, stored in CSR format, only uses 527 MB. That is a 2x savings on memory usage!\r\n<table>\r\n<tbody>\r\n<tr>\r\n<th>Matrix Elements</th>\r\n<th>Memory Size (Dense)</th>\r\n<th>Memory Size (Sparse)</th>\r\n<th>CG Time (Dense)</th>\r\n<th>CG Time (Sparse)</th>\r\n</tr>\r\n<tr>\r\n<th>16M x 16M</th>\r\n<th>1024 MB</th>\r\n<th>527 MB</th>\r\n<th>64.94ms</th>\r\n<th>39.31ms</th>\r\n</tr>\r\n<tr>\r\n<th>4M x 4M</th>\r\n<th>64 MB</th>\r\n<th>33 MB</th>\r\n<th>4.752ms</th>\r\n<th>3.935ms</th>\r\n</tr>\r\n</tbody>\r\n</table>\r\nSparse arrays will now let users store more data on the GPU while allowing faster computation, thus allowing to solve for bigger, more complex problems.\r\n\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Download[/custom_headline]\r\n\r\nArrayFire v3.4 can be downloaded from these locations:\r\n<ul>\r\n 	<li><a href=\"http://sandbox.arrayfire.com/download/\">Binaries</a></li>\r\n 	<li><a href=\"https://github.com/arrayfire\">Source code</a></li>\r\n</ul>\r\n[custom_headline type=\"left\" level=\"h3\" looks_like=\"h3\"]Community[/custom_headline]\r\n\r\nArrayFire is continually improving through the addition of new sparse matrix enhancements. We welcome your feedback:\r\n<ul>\r\n 	<li>General discussion forums on the <a href=\"https://groups.google.com/forum/#!forum/arrayfire-users\">ArrayFire Google Group</a></li>\r\n 	<li>Live discussion chat on the <a href=\"https://gitter.im/arrayfire/arrayfire?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge\">ArrayFire Gitter</a></li>\r\n 	<li>Issue reports on the <a href=\"https://github.com/arrayfire/arrayfire/issues\">ArrayFire GitHub</a></li>\r\n</ul>\r\nFinally, as you find success with ArrayFire, we invite you to contribute a post to this blog to share with the broader community. Email <a href=\"mailto:scott@arrayfire.com\">scott@arrayfire.com</a> to contribute to this blog.','Sparse Matrices in ArrayFire v3.4','','publish','open','closed','','sparse-matrices-in-arrayfire-v3-4','','','2016-09-21 22:41:40','2016-09-22 02:41:40','',0,'http://sandbox.arrayfire.com/?p=9190',0,'post','',0),(9191,17729,'2016-09-19 14:09:28','2016-09-19 18:09:28','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector fields in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:09:28','2016-09-19 18:09:28','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9192,17729,'2016-09-19 14:10:50','2016-09-19 18:10:50','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector fields in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:10:50','2016-09-19 18:10:50','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9193,17729,'2016-09-19 14:12:51','2016-09-19 18:12:51','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:12:51','2016-09-19 18:12:51','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9194,17729,'2016-09-19 14:13:32','2016-09-19 18:13:32','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is another screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:13:32','2016-09-19 18:13:32','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9195,17729,'2016-09-19 14:13:59','2016-09-19 18:13:59','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Deprecated_and_their_replacements_2\"></a>Deprecated and their replacements</h5>\r\n<h6><a id=\"C_API_4\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_plot</code> has been deprecated in favour of <code>af_draw_plot_2d</code> or <code>af_draw_plot_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_plot3</code> has been deprecated in favour of <code>af_draw_plot_3d</code> or <code>af_draw_plot_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter</code> has been deprecated in favour of <code>af_draw_scatter_2d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>2d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n<li><code>af_draw_scatter3</code> has been deprecated in favour of <code>af_draw_scatter_3d</code> or <code>af_draw_scatter_nd</code> where the function with <strong>3d</strong> suffix is specific to two dimensional plots and the version with <strong>nd</strong> suffix is generalised.</li>\r\n</ul>\r\n<h6><a id=\"C_API_9\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::plot3</code> has been deprecated in favour of <code>af::Window::plot</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n<li><code>af::Window::scatter3</code> has been deprecated in favour of <code>af::Window::scatter</code>, which is generalized plotting draw call that can handle both 2d and 3d data.</li>\r\n</ul>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:13:59','2016-09-19 18:13:59','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9196,17729,'2016-09-19 14:39:28','2016-09-19 18:39:28','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 14:39:28','2016-09-19 18:39:28','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9197,4,'2016-09-19 14:43:49','2016-09-19 18:43:49','<span style=\"font-weight: 400;\">A lot has happened since the last ArrayFire release and a lot has changed. We have tackled a large number of issues on <a href=\"https://github.com/arrayfire/arrayfire\">GitHub</a> from our ever growing community of users and contributors and we have introduced significant improvements and functions to our library. </span><span style=\"font-weight: 400;\">What has not changed though, is our passion for pushing the boundaries of computational hardware and our commitment to giving our users an unprecedented degree of freedom to create lightning fast software faster than ever before.</span>\r\n\r\n<span style=\"font-weight: 400;\">With this enthusiasm, we would like to announce the release of Arrayfire v3.4.</span>\r\n\r\n<strong>Major Updates and New Features</strong>\r\n<ul>\r\n 	<li>Sparse Matrix and BLAS\r\n<ul>\r\n 	<li>Support for CSR and COO storage types</li>\r\n 	<li>Sparse-Dense Matrix Multiplication and Matrix-Vector Multiplication</li>\r\n 	<li>Conversion to and from dense matrix to CSR and COO storage types</li>\r\n</ul>\r\n</li>\r\n 	<li>Faster JIT for CUDA and OpenCL\r\n<ul>\r\n 	<li>Performance improvements</li>\r\n 	<li>Support for evaluating multiple outputs in a single kernel</li>\r\n</ul>\r\n</li>\r\n 	<li>Support for random number generator engines\r\n<ul>\r\n 	<li>Philox</li>\r\n 	<li>Threefry</li>\r\n 	<li>Mersenne Twister</li>\r\n</ul>\r\n</li>\r\n 	<li>Improvements to graphics\r\n<ul>\r\n 	<li>Using Forge v0.9.0</li>\r\n 	<li>Vector Field plotting functionality</li>\r\n 	<li>Multiple overlays on the same window are now possible</li>\r\n 	<li>New API to set axes limits for graphs</li>\r\n 	<li>New API for plot and scatter</li>\r\n</ul>\r\n</li>\r\n</ul>\r\nThere are numerous other improvements such as new interpolation methods, image moments, scan by key and so on. For the comprehensive list of improvements and bug fixes, please refer to our <a href=\"http://arrayfire.org/docs/releasenotes.htm\">release notes</a>.\r\n\r\n<span style=\"font-weight: 400;\">While we are happy for reaching this milestone, we are not complacent. Work on the next milestone is continuing on full steam and we hope to exceed the expectations of our community.</span>','ArrayFire v3.4 Official Release','','inherit','closed','closed','','9154-revision-v1','','','2016-09-19 14:43:49','2016-09-19 18:43:49','',9154,'http://sandbox.arrayfire.com/9154-revision-v1/',0,'revision','',0),(9198,4,'2016-09-19 15:13:33','2016-09-19 19:13:33','<span style=\"font-weight: 400;\">Today we are pleased to announce the release of ArrayFire v3.4, our open source library of parallel computing functions supporting CUDA, OpenCL, and CPU host processing. This new version contains additions and updates that improve features and performance for applications in machine learning, computer vision, signal processing, statistics, finance, and more.</span>\r\n\r\n<span style=\"font-weight: 400;\">This release focuses on 4 major areas of the library that are common to many areas of mathematical, scientific, and financial computing:  sparse matrix operations, random number generation, just-in-time (JIT) compilation, and visualizations.</span>\r\n\r\n<strong>Major Updates and New Features</strong>\r\n<ul>\r\n 	<li>Sparse Matrix and BLAS\r\n<ul>\r\n 	<li>Support for CSR and COO storage types</li>\r\n 	<li>Sparse-Dense Matrix Multiplication and Matrix-Vector Multiplication</li>\r\n 	<li>Conversion to and from dense matrix to CSR and COO storage types</li>\r\n</ul>\r\n</li>\r\n 	<li>Support for random number generator engines\r\n<ul>\r\n 	<li>Philox</li>\r\n 	<li>Threefry</li>\r\n 	<li>Mersenne Twister</li>\r\n</ul>\r\n</li>\r\n 	<li>Faster JIT for CUDA and OpenCL\r\n<ul>\r\n 	<li>Performance improvements</li>\r\n 	<li>Support for evaluating multiple outputs in a single kernel</li>\r\n</ul>\r\n</li>\r\n 	<li>Improvements to graphics\r\n<ul>\r\n 	<li>Using Forge v0.9.0</li>\r\n 	<li>Vector Field plotting functionality</li>\r\n 	<li>Multiple overlays on the same window are now possible</li>\r\n 	<li>New API to set axes limits for graphs</li>\r\n 	<li>New API for plot and scatter</li>\r\n</ul>\r\n</li>\r\n</ul>\r\nThere are numerous other improvements such as new interpolation methods, image moments, scan by key and so on. For the comprehensive list of improvements and bug fixes, please refer to our <a href=\"http://arrayfire.org/docs/releasenotes.htm\">release notes</a>.\r\n\r\n<span style=\"font-weight: 400;\">While we are happy for reaching this milestone, we are not complacent. Work on the next milestone is continuing on full steam and we hope to exceed the expectations of our community.</span>','ArrayFire v3.4 Official Release','','inherit','closed','closed','','9154-revision-v1','','','2016-09-19 15:13:33','2016-09-19 19:13:33','',9154,'http://sandbox.arrayfire.com/9154-revision-v1/',0,'revision','',0),(9199,17729,'2016-09-19 15:29:01','2016-09-19 19:29:01','','swe','','inherit','open','closed','','swe-2','','','2016-09-19 15:29:01','2016-09-19 19:29:01','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif',0,'attachment','image/gif',0),(9200,17729,'2016-09-19 15:29:18','2016-09-19 19:29:18','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<h6><a id=\"C_API_16\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_set_axes_limits_compute</code> computes the axes limits from given <code>af_array</code>\'s and then passed the same to draw call.</li>\r\n<li><code>af_set_axes_limits_2d</code> can be used to explicitly set the x and y axes limits to specific minimum and maximum values.</li>\r\n<li><code>af_set_axes_limits_3d</code> can be used to explicitly set the x, y &amp; z axes limits to specific minimum and maximum values.</li>\r\n</ul>\r\n<h6><a id=\"C_API_20\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 15:29:18','2016-09-19 19:29:18','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9201,17729,'2016-09-19 15:59:01','2016-09-19 19:59:01','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Following are the new API calls for setting axes limits.</p>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 15:59:01','2016-09-19 19:59:01','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9202,17729,'2016-09-19 16:00:11','2016-09-19 20:00:11','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Given below is the new API for setting axes limits.</p>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<p>Any new functions that have been already mentioned in the above two sections are not repeated below.</p>\r\n<h6><a id=\"C_API_58\"></a>C API</h6>\r\n<ul>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_2d</code> renders given data as two dimensional vector field</li>\r\n<li><code>af_draw_vector_field_nd</code> is generalized version that can handle both 2d and 3d <code>af_array</code>s.</li>\r\n<li><code>af_set_axes_titles</code> can be used to set the titles of axes of a given chart/graph.</li>\r\n</ul>\r\n<h6><a id=\"C_API_63\"></a>C++ API</h6>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:00:11','2016-09-19 20:00:11','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9203,17729,'2016-09-19 16:01:17','2016-09-19 20:01:17','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot. Given below is the new API for setting axes limits.</p>\r\n<ul>\r\n<li><code>af::Window::setAxesLimits</code></li>\r\n</ul>\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n<ul>\r\n<li><code>af::Window::vectorField</code> is an overloaded and generalized vector field rendering function.</li>\r\n<li><code>af::Window::setAxesTitles</code> is used to set the chart/graph axes labels</li>\r\n</ul>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new functions, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:01:17','2016-09-19 20:01:17','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9204,17729,'2016-09-19 16:03:19','2016-09-19 20:03:19','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 3d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:03:19','2016-09-19 20:03:19','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9205,17729,'2016-09-19 16:04:19','2016-09-19 20:04:19','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.gif\" alt=\"swe\" width=\"800\" height=\"600\" class=\"alignnone size-full wp-image-9199\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:04:19','2016-09-19 20:04:19','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9206,17729,'2016-09-19 16:04:54','2016-09-19 20:04:54','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot</li>\r\n<li>hist</li>\r\n<li>surface</li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:04:54','2016-09-19 20:04:54','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9207,17729,'2016-09-19 16:11:07','2016-09-19 20:11:07','','histogram','','inherit','open','closed','','histogram','','','2016-09-19 16:11:07','2016-09-19 20:11:07','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png',0,'attachment','image/png',0),(9210,17729,'2016-09-19 16:11:55','2016-09-19 20:11:55','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3-150x150.png\" alt=\"plot3\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-9208\" /></a></li>\r\n<li>histogram <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram-300x152.png\" alt=\"histogram\" width=\"300\" height=\"152\" class=\"alignnone size-medium wp-image-9207\" /></a></li>\r\n<li>surface <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface-300x300.png\" alt=\"surface\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9209\" /></a></li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:11:55','2016-09-19 20:11:55','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9211,17729,'2016-09-19 16:15:30','2016-09-19 20:15:30','','plot3','','inherit','open','closed','','plot3','','','2016-09-19 16:15:30','2016-09-19 20:15:30','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png',0,'attachment','image/png',0),(9212,17729,'2016-09-19 16:15:33','2016-09-19 20:15:33','','surface','','inherit','open','closed','','surface','','','2016-09-19 16:15:33','2016-09-19 20:15:33','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png',0,'attachment','image/png',0),(9213,17729,'2016-09-19 16:16:17','2016-09-19 20:16:17','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3-300x300.png\" alt=\"plot3\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9211\" /></a></li>\r\n<li>histogram <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram-300x152.png\" alt=\"histogram\" width=\"300\" height=\"152\" class=\"alignnone size-medium wp-image-9207\" /></a></li>\r\n<li>surface <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface-300x300.png\" alt=\"surface\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9212\" /></a></li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:16:17','2016-09-19 20:16:17','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9216,17729,'2016-09-19 16:36:13','2016-09-19 20:36:13','','gravity','','inherit','open','closed','','gravity','','','2016-09-19 16:36:13','2016-09-19 20:36:13','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif',0,'attachment','image/gif',0),(9217,17729,'2016-09-19 16:36:58','2016-09-19 20:36:58','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li>plot <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3-300x300.png\" alt=\"plot3\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9211\" /></a></li>\r\n<li>histogram <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram-300x152.png\" alt=\"histogram\" width=\"300\" height=\"152\" class=\"alignnone size-medium wp-image-9207\" /></a></li>\r\n<li>surface <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface-300x300.png\" alt=\"surface\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9212\" /></a></li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\nWhile taking screen shots for the images for new rendering functions, i found the gifs for our simple yet fun to watch examples - conway and gravity simulation. \r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway-300x300.gif\" alt=\"conway\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9214\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty-300x300.gif\" alt=\"conway_pretty\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9215\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\" alt=\"gravity\" width=\"256\" height=\"256\" class=\"alignnone size-full wp-image-9216\" /></a>\r\nHere you go, enjoy the gifs! You can find the code for these samples here, <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/conway.cpp\" target=\"_blank\">conway</a> and <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/gravity_sim.cpp\" target=\"_blank\">gravity</a>.\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:36:58','2016-09-19 20:36:58','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9218,17729,'2016-09-19 16:38:20','2016-09-19 20:38:20','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot3.cpp\" target=\"_blank\">plot</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3-300x300.png\" alt=\"plot3\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9211\" /></a></li>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/histogram.cpp\" target=\"_blank\">histogram</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram-300x152.png\" alt=\"histogram\" width=\"300\" height=\"152\" class=\"alignnone size-medium wp-image-9207\" /></a></li>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/surface.cpp\" target=\"_blank\">surface</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface-300x300.png\" alt=\"surface\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9212\" /></a></li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\nWhile taking screen shots for the images for new rendering functions, i found the gifs for our simple yet fun to watch examples - conway and gravity simulation. \r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway-300x300.gif\" alt=\"conway\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9214\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty-300x300.gif\" alt=\"conway_pretty\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9215\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\" alt=\"gravity\" width=\"256\" height=\"256\" class=\"alignnone size-full wp-image-9216\" /></a>\r\nHere you go, enjoy the gifs! You can find the code for these samples here, <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/conway.cpp\" target=\"_blank\">conway</a> and <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/gravity_sim.cpp\" target=\"_blank\">gravity</a>.\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:38:20','2016-09-19 20:38:20','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9219,11,'2016-09-19 16:40:25','2016-09-19 20:40:25','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\nSparse Data Structure\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are >> number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n* A data or values array containing all the non-zero elements\r\n* A vector for row indices (based on storage format).\r\n* A vector for column indices (based on storage format).\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\nSparse in ArrayFire\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\nSparse Functionality\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n  * To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n  * Sparse Matrix - Dense Matrix\r\n  * Sparse Matrix - Dense Vector\r\n  * Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\nExample\r\n\r\n\r\nPerformance and Memory Footprint\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:40:25','2016-09-19 20:40:25','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9220,17729,'2016-09-19 16:40:30','2016-09-19 20:40:30','<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Untitled Document.md</title><style></style></head><body id=\"preview\">\r\n<p>This post outlines the new graphics features and updates that come along with ArrayFire v3.4.0 release.</p>\r\n<h5><a id=\"Behavioral_Changes_13\"></a>Behavioral Changes</h5>\r\n<p>Prior to v3.4.0 release, all plotting functions used to compute the axes limits pertaining to corresponding data automatically. This additional step of computing axes is now not performed in any plotting functions. Instead, new API has been provided to set the axes limits of the corresponding graph plot.\r\n\r\n<p>Given below is an example showing the code changes one has to make to their C++ ArrayFire program that uses graphics functionality of ArrayFire.</p>\r\n\r\n<pre><code class=\"language-cpp\">\r\naf::Window myWindow(800, 800, \"2D Plot example: ArrayFire\");\r\n\r\narray Y;\r\nint sign = 1;\r\narray X = seq(-af::Pi, af::Pi, PRECISION);\r\narray noise = randn(X.dims(0))/5.f;\r\n\r\nmyWindow.grid(2, 1);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(0, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1, 1, true);\r\n// Set the axes limits to view (0,0), prior to v3.4 this was not needed\r\nmyWindow(1, 0).setAxesLimits(-2 * af::Pi, 2 * af::Pi, -1.25, 1.25, true);\r\n\r\nfor (double val=0; !myWindow.close(); )\r\n{\r\n    Y = sin(X);\r\n\r\n    myWindow(0,0).plot(X, Y);\r\n    myWindow(1,0).scatter(X, Y + noise, AF_MARKER_POINT);\r\n\r\n    myWindow.show();\r\n\r\n    X = X + PRECISION * float(sign);\r\n    val += PRECISION * float(sign);\r\n\r\n    if (val>af::Pi) {\r\n        sign = -1;\r\n    } else if (val<-af::Pi) {\r\n        sign = 1;\r\n    }\r\n}\r\n</code></pre>\r\n<p>Above code should render as the following and you can find the complete example <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot2d.cpp\" target=\"_blank\">here</a>.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot2d-1024x927.png\" alt=\"plot2d\" width=\"742\" height=\"672\" class=\"alignnone size-large wp-image-9183\" /></a>\r\n\r\n<h5><a id=\"New_Features_56\"></a>New Features</h5>\r\n\r\n<h6>Vector Fields</h6>\r\n<p>An example of how to render your data as a vector field has been provided in our examples which you can find <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/field.cpp\" target=\"_blank\">here</a>. This example shows a static and dynamic vector field in multi-view mode. Given below is the screenshot of this example while running.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/vfield-1024x550.png\" alt=\"vfield\" width=\"742\" height=\"399\" class=\"alignnone size-large wp-image-9185\" /></a>\r\n\r\n<p>Apart from the above new renderables, each window/view supports overlay of different renderables now. If you are not already aware of what a view (graphics context) in ArrayFire is: Each draw call in ArrayFire is either rendered to whole window(single view) or a portion of the screen(multiview mode or grid mode), this subset portion of the whole window is called a view.\r\n\r\n<p>Given below is a screen shot of mult-view mode which renders an image, 2d line plot, histogram and surface. You can find the corresponding example code <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/pde/swe.cpp\" target=\"_blank\">here</a>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/swe-1024x549.png\" alt=\"swe\" width=\"742\" height=\"398\" class=\"alignnone size-large wp-image-9184\" /></a>\r\n\r\nThe following renerables support overlay if they are of same type of object (2d/3d).</p>\r\n<ul>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/plot3.cpp\" target=\"_blank\">plot</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/plot3-300x300.png\" alt=\"plot3\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9211\" /></a></li>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/histogram.cpp\" target=\"_blank\">histogram</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/histogram-300x152.png\" alt=\"histogram\" width=\"300\" height=\"152\" class=\"alignnone size-medium wp-image-9207\" /></a></li>\r\n<li><a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/surface.cpp\" target=\"_blank\">surface</a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/surface-300x300.png\" alt=\"surface\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9212\" /></a></li>\r\n<li>vector fields</li>\r\n</ul>\r\n<p>You can see an example screenshot of how overlay of plots looks like below.</p>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/multipleplot.png\" alt=\"multipleplot\" width=\"1002\" height=\"828\" class=\"alignnone size-full wp-image-9182\" /></a>\r\n\r\nWhile taking screen shots for the images for new rendering functions, i found the gifs for our simple yet fun to watch examples - conway and gravity simulation. \r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway.gif\" alt=\"conway\" width=\"512\" height=\"512\" class=\"alignnone size-full wp-image-9214\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty-300x300.gif\" alt=\"conway_pretty\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-9215\" /></a> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2016/09/gravity.gif\" alt=\"gravity\" width=\"256\" height=\"256\" class=\"alignnone size-full wp-image-9216\" /></a>\r\nHere you go, enjoy the gifs! You can find the code for these samples here, <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/conway.cpp\" target=\"_blank\">conway</a> and <a href=\"https://github.com/arrayfire/arrayfire/blob/devel/examples/graphics/gravity_sim.cpp\" target=\"_blank\">gravity</a>.\r\n\r\n<h5><a id=\"Misc_Changes_74\"></a>Misc Changes</h5>\r\n<p>Removed <a href=\"http://glew.sourceforge.net/\">GLEW</a> and replaced with <a href=\"https://github.com/cginternals/glbinding\">glbinding</a>.</p>\r\n<h5><a id=\"Conclusion_77\"></a>Conclusion</h5>\r\n<p>We intend to add more graphcis functionality in future releases, keep checking for new posts from us. Please do try the new graphics functionality and kindly let us know if you find any bugs in the library.</p>\r\n\r\n</body></html>','Graphics updates in ArrayFire v3.4.0','','inherit','closed','closed','','9172-revision-v1','','','2016-09-19 16:40:30','2016-09-19 20:40:30','',9172,'http://sandbox.arrayfire.com/9172-revision-v1/',0,'revision','',0),(9221,11,'2016-09-19 16:40:38','2016-09-19 20:40:38','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n## Sparse Data Structure\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are >> number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n* A data or values array containing all the non-zero elements\r\n* A vector for row indices (based on storage format).\r\n* A vector for column indices (based on storage format).\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\nSparse in ArrayFire\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\nSparse Functionality\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n  * To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n  * <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n  * Sparse Matrix - Dense Matrix\r\n  * Sparse Matrix - Dense Vector\r\n  * Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\nExample\r\n\r\n\r\nPerformance and Memory Footprint\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:40:38','2016-09-19 20:40:38','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9222,11,'2016-09-19 16:41:26','2016-09-19 20:41:26','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h3>Sparse Data Structure</h3>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n* A data or values array containing all the non-zero elements\r\n* A vector for row indices (based on storage format).\r\n* A vector for column indices (based on storage format).\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\nSparse in ArrayFire\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\nSparse Functionality\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\nExample\r\n\r\nPerformance and Memory Footprint\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:41:26','2016-09-19 20:41:26','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9223,11,'2016-09-19 16:42:56','2016-09-19 20:42:56','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h4>Sparse Data Structure</h4>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n* A data or values array containing all the non-zero elements\r\n* A vector for row indices (based on storage format).\r\n* A vector for column indices (based on storage format).\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n<h4>Sparse in ArrayFire</h4>\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\n<h4>Sparse Functionality</h4>\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\n<h4>Example</h4>\r\n\r\n<h4>Performance and Memory Footprint</h4>\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:42:56','2016-09-19 20:42:56','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9224,11,'2016-09-19 16:43:13','2016-09-19 20:43:13','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h4>Sparse Data Structure</h4>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n<ul>\r\nA data or values array containing all the non-zero elements\r\nA vector for row indices (based on storage format).\r\nA vector for column indices (based on storage format).\r\n</ul>\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n<h4>Sparse in ArrayFire</h4>\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\n<h4>Sparse Functionality</h4>\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\n<h4>Example</h4>\r\n\r\n<h4>Performance and Memory Footprint</h4>\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:43:13','2016-09-19 20:43:13','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9225,11,'2016-09-19 16:43:47','2016-09-19 20:43:47','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h4>Sparse Data Structure</h4>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n<ol>\r\nA data or values array containing all the non-zero elements\r\nA vector for row indices (based on storage format).\r\nA vector for column indices (based on storage format).\r\n</ol>\r\n\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n<h4>Sparse in ArrayFire</h4>\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\n<h4>Sparse Functionality</h4>\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\n<h4>Example</h4>\r\n\r\n<h4>Performance and Memory Footprint</h4>\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:43:47','2016-09-19 20:43:47','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9226,11,'2016-09-19 16:43:57','2016-09-19 20:43:57','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h4>Sparse Data Structure</h4>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n<ol>\r\n<ol> A data or values array containing all the non-zero elements\r\nA vector for row indices (based on storage format).\r\nA vector for column indices (based on storage format).\r\n</ol>\r\n\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n<h4>Sparse in ArrayFire</h4>\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\n<h4>Sparse Functionality</h4>\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\n<h4>Example</h4>\r\n\r\n<h4>Performance and Memory Footprint</h4>\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:43:57','2016-09-19 20:43:57','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),(9227,17729,'2016-09-19 16:44:18','2016-09-19 20:44:18','','conway','','inherit','open','closed','','conway','','','2016-09-19 16:44:18','2016-09-19 20:44:18','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway.gif',0,'attachment','image/gif',0),(9228,17729,'2016-09-19 16:44:20','2016-09-19 20:44:20','','conway_pretty','','inherit','open','closed','','conway_pretty','','','2016-09-19 16:44:20','2016-09-19 20:44:20','',9172,'http://sandbox.arrayfire.com/wp-content/uploads/2016/09/conway_pretty.gif',0,'attachment','image/gif',0),(9229,11,'2016-09-19 16:44:39','2016-09-19 20:44:39','With the release of <strong>ArrayFire v3.4</strong>, we have added a number of features that will help our vast range of users. Our users have been asking us for a way to reduce the memory footprint of their data on the GPU. And now we have answered our users\' requests.\r\nIntroducing Sparse Matrices in ArrayFire!\r\n\r\n<h4>Sparse Data Structure</h4>\r\nA sparse data structure is one where all the non-zero elements are not stored. Sparse matrices are useful when the number of zero-values elements are &gt;&gt; number of non-zero elements (sparsity of the matrix is high).\r\nThe sparse data structure in general is stored as 3 arrays.\r\n<ul>\r\n<li>A data or values array containing all the non-zero elements</li>\r\n<li>A vector for row indices (based on storage format).</li>\r\n<li>A vector for column indices (based on storage format).</li>\r\n</ul>\r\n\r\n\r\nThere are many ways to store sparse matrices, the most prominent of which are <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29\">Compressed Sparse Row</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29\">Compressed Storage Column</a>, <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29\">Coordinate Format</a>. ArrayFire supports CSR and COO format, with CSC support coming in future releases.\r\n\r\nA more detailed description of Sparse Matrix can be found on <a href=\"https://en.wikipedia.org/wiki/Sparse_matrix\">Wikipedia</a>.\r\n\r\n<h4>Sparse in ArrayFire</h4>\r\nIn ArrayFire, Sparse arrays use the same user facing object - af::array. This makes working with sparse arrays all the more seamless.\r\nWe have added a function <a href=\"http://arrayfire.org/docs/group__method__mat.htm#ga5945f95549bae25f75694a69d98ca584\">af::array::issparse()</a> that allows users to check if an array is sparse or not.\r\nAlthough externally, there is no difference between a sparse and dense array, internally, the sparse array is stored as 3 independent arrays along with other meta data.\r\nThese arrays, as well as other properties can be fetched using the <a href=\"http://arrayfire.org/docs/group__sparse__func.htm\">sparse functions</a>.\r\n\r\n<h4>Sparse Functionality</h4>\r\nAs of v3.4, the following features are supported for sparse arrays:\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm\">Creation for sparse arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae4621e58bfaf6d80668309824fde86c0\">From 3 (data, row, column) sparse host or device memory vectors.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gae9a843c7e93b05e6b090ca32b271ebe9\">From 3 (data, row, column) sparse af::arrays.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">From dense af::array.</a>\r\n* To create a sparse array from host or device dense array, first create a dense af::array, and then pass it to create sparse af::array from dense af::array.\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__convert__to.htm\">Storage format conversions.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__create.htm#gac0d367d8c9daf27b36a6981bbfcdb970\">Dense to CSR/COO.</a>\r\n* <a href=\"http://arrayfire.org/docs/group__sparse__func__dense.htm\">CSR/COO to dense.</a>\r\n* Sparse-Dense Matrix Multiplication (SPMM/SPMV)\r\n* Sparse Matrix - Dense Matrix\r\n* Sparse Matrix - Dense Vector\r\n* Options for Sparse Matrix to be transposed.\r\nThe Sparse-Dense Matrix Multiplcation is a implemented as a part of <a href=\"http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b\">af::matmul()</a>. This is part of making the usage of sparse arrays seamless with regular arrays.\r\n\r\n<h4>Example</h4>\r\n\r\n<h4>Performance and Memory Footprint</h4>\r\n\r\nAs with all ArrayFire features, Sparse support is available across all backends and all architectures.','Sparse Matrices in ArrayFire','','inherit','closed','closed','','9190-revision-v1','','','2016-09-19 16:44:39','2016-09-19 20:44:39','',9190,'http://sandbox.arrayfire.com/9190-revision-v1/',0,'revision','',0),