[arrayfire] 20/61: forge visualization tutorial

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Tue Dec 8 11:55:03 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch dfsg-clean
in repository arrayfire.

commit aa076e96e8b7fa547d6ac400832eba994de067bc
Author: syurkevi <stefan at arrayfire.com>
Date:   Thu Nov 19 14:11:16 2015 -0500

    forge visualization tutorial
---
 assets                            |   2 +-
 docs/layout.xml                   |   2 +
 docs/pages/forge_visualization.md | 110 ++++++++++++++++++++++++++++++++++++++
 docs/pages/vectorization.md       |  67 ++++++++++-------------
 4 files changed, 141 insertions(+), 40 deletions(-)

diff --git a/assets b/assets
index 7c2a127..8030a5c 160000
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit 7c2a12739ac0f5830d26334731e9ac96ba01e2d7
+Subproject commit 8030a5c626777a5b3f46b319dd4d1723eca4b0f9
diff --git a/docs/layout.xml b/docs/layout.xml
index 3a66b56..720e9d6 100644
--- a/docs/layout.xml
+++ b/docs/layout.xml
@@ -10,6 +10,8 @@
       <tab type="user" url="\ref gettingstarted" visible="yes" title="Getting Started"/>
       <tab type="user" url="\ref unifiedbackend" visible="yes" title="Unified Backend"/>
       <tab type="user" url="\ref matrixmanipulation" visible="yes" title="Matrix Manipulation"/>
+      <tab type="user" url="\ref vectorization" visible="yes" title="Vectorization"/>
+      <tab type="user" url="\ref forge_visualization" visible="yes" title="Forge Visualization"/>
       <tab type="user" url="\ref indexing" visible="yes" title="Indexing"/>
       <tab type="user" url="\ref timing" visible="yes" title="Timing ArrayFire"/>
       <tab type="user" url="\ref configuring_environment" visible="yes" title="Configuring ArrayFire Environment"/>
diff --git a/docs/pages/forge_visualization.md b/docs/pages/forge_visualization.md
new file mode 100644
index 0000000..6107fb3
--- /dev/null
+++ b/docs/pages/forge_visualization.md
@@ -0,0 +1,110 @@
+Visualizing af::arrays with Forge {#forge_visualization}
+===================
+Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing. The goal of Forge, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context. 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! Furthermore, Arrayfire provides wrapp [...]
+
+# Setup
+Before we can call Forge functions, we need to set up the related "canvas" classes. Forge functions are tied to the af::Window class. First let's create a window:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+const static int WIDTH = 512, HEIGHT = 512;
+af::Window window(WIDTH, HEIGHT, "2D plot example title");
+
+do{
+
+//drawing functions here
+
+} while( !window.close() );
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
+# af::Window::image
+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. Let's see this on a static noise example:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array img = constant(0, WIDTH, HEIGHT); //make a black image
+array random = randu(WIDTH, HEIGHT);      //make random [0,1] distribution
+img(random > 0.5) = 1; //set all pixels where distribution > 0.5 to white
+
+window.image(img);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<img src="gfx_docs_images/noise.png" alt="Forge image plot of noise" width="20%" />
+Tweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array img = 255 * randu(WIDTH, HEIGHT, 3);      //make random [0, 255] distribution
+window.image( img.as(u8) );
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<img src="gfx_docs_images/color_noise.png" alt="Forge image plot of color noise" width="20%" />
+Notice 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 [0, 255]. The type-handling properties are consistent for all Forge drawing functions.
+
+# af::Window::plot
+The af::Window::plot() function visualizes an array as a 2d-line plot. Let's see a simple example:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array X = seq(-af::Pi, af::Pi, 0.01);
+array Y = sin(X);
+window.plot(X, Y);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+<img src="gfx_docs_images/sin_plot.png" alt="Forge 2d line plot of sin() function" width="30%" />
+The plot function has the signature:
+<br> **void plot( const array &X, const array &Y, const char * const title = NULL );**
+<br> Both the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array t = seq(0, 100, 0.01);
+array X = sin(t) * (exp(cos(t)) - 2*cos(4*t) - pow(sin(t/12), 5)); array Y = cos(t) * (exp(cos(t)) - 2*cos(4*t) - pow(sin(t/12), 5));
+window.plot(X, Y);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+<img src="gfx_docs_images/butterfly_plot.png" alt="Forge 2d line plot of butterfly function" width="30%" />
+
+# af::Window::plot3
+The af::Window::plot3() function will plot a curve in 3d-space.
+Its signature is:
+<br> **void plot3 (const array &in, const char * title = NULL);**
+<br> The input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional <i>(3n x 1)</i> array, or in one of the <i>(3 x n),</i> <i>(n x 3)</i> matrix forms.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array Z = seq(0.1f, 10.f, 0.01);
+array Y = sin(10*Z) / Z;
+array X = cos(10*Z) / Z;
+
+array Pts = join(1, X, Y, Z);
+//Pts can be passed in as a matrix in the from n x 3, 3 x n
+//or in the flattened xyz-triplet array with size 3n x 1
+window.plot3(Pts);
+//both of the following are equally valid
+//window.plot3(transpose(Pts));
+//window.plot3(flat(Pts));
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<img src="gfx_docs_images/spiral_plot3.png" alt="Forge 3d line plot" width="40%" />
+
+# af::Window::hist
+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.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+const int BINS = 128; SAMPLES = 9162;
+array norm = randn(SAMPLES);
+array hist_arr = histogram(norm, BINS);
+
+win.hist(hist_arr, 0, BINS);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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: **void hist(const array & X, const double minval, const double maxval, const char * const title = NULL);**
+<img src="gfx_docs_images/norm_histogram.png" alt="Forge 3d scatter plot" width="40%" />
+
+
+# af::Window::surface
+The af::Window::surface() function will plot af::arrays as a 3d surface.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+array Z = randu(21, 21);
+window.surface(Z, "Random Surface");    //equal to next function call
+//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, "Random Surface");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<img src="gfx_docs_images/rand_surface.png" alt="Forge random surface plot" width="30%" />
+There are two overloads for the **af::Window::surface()** function:
+* **void surface (const array & S, const char *const title )** -- accepts a 2d matrix with the z values of the surface
+* **void surface (const array &xVals, const array &yVals, const array &S, const char * const title)** -- accepts additional vectors that define the x,y coordinates for the surface points.
+
+The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size **m x n**:
+ 1. Short vectors defining the spacing along each axis. Vectors will have sizes **m x 1** and **n x 1**.
+ 2. Vectors containing the coordinates of each and every point. Each of the vectors will have length **mn x 1**. This can be used for completely non-uniform or parametric surfaces.
+
+# Conclusion
+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.
diff --git a/docs/pages/vectorization.md b/docs/pages/vectorization.md
index b7e7704..2061172 100644
--- a/docs/pages/vectorization.md
+++ b/docs/pages/vectorization.md
@@ -3,7 +3,7 @@ Vectorization {#vectorization}
 
 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 [...]
 
-### Generic/Default vectorization
+# Generic/Default vectorization
 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:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
 af::array a = af::seq(10); // [0,  9]
@@ -19,35 +19,24 @@ af::array a = af::seq(10);  // [0,  9]
 a = a + 1;                  // [1, 10]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Some of the vectorized mathematical functions of Arrayfire include:  
-
-__Arithmetic operations:__
- 	+, -, *, /, >>, <<
-
-__Complex operations:__
- 	real, imag, conjugate, etc. 
- 	 
-__Exponential and logarithmic functions:__
- 	exp, log, expm1, log1p, etc. 
- 
-__Hyperbolic functions:__
- 	sinh, cosh, tanh, etc. 
- 
-__Logical operations:__
- 	&&, ||, |, &, <, >, <=, >=, ==, ! 
- 
-__Numeric functions:__
- 	floor, round, min, max, etc. 
- 
-__Trigonometric functions:__
- 	sin, cos, tan, etc. 
-  
-  
-### GFOR: Parallel for-loops
+Some of the vectorized mathematical functions of Arrayfire include:
+
+Operator Category                     | Functions
+--------------------------------------|--------------------------
+Arithmetic operations                 | operator+(), operator-(), operator*(), operator/(), operator>>(), operator<<()
+Complex operations                    | real(), imag(), conjugate(), etc.
+Exponential and logarithmic functions | exp(), log(), expm1(), log1p(), etc.
+Hyperbolic functions                  | sinh(), cosh(), tanh(), etc.
+Numeric functions                     | floor(), round(), min(), max(), etc.
+Trigonometric functions               | sin(), cos(), tan(), etc.
+Logical operations                    | &&, \|\|, \|, &, <, >, <=, >=, ==, !
+
+
+# GFOR: Parallel for-loops
 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.  
-We can remedy our first example with GFOR:  
+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.
+We can remedy our first example with GFOR:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
 af::array a = af::seq(10);
 gfor(seq i, n)
@@ -62,8 +51,8 @@ for (int i = 0; i < N; ++i)
 gfor (seq i, N)
    A(span,span,i) = fft2(A(span,span,i)); // runs N FFTs in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-### GFOR: Usage
-There are three formats for instantiating gfor-loops:  
+## GFOR: Usage
+There are three formats for instantiating gfor-loops:
 
  1. gfor(var,n)-- Creates a sequence <B>{0, 1, ..., n-1}</B>
  2. gfor(var,first,last)-- Creates a sequence <B>{first, first+1, ..., last}</B>
@@ -78,8 +67,8 @@ gfor (seq i, 0, 1, 4)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 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="page_gfor.htm">GFOR documentation.</a>
 
-### batchFunc()
-The batchFunc() 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. 
+# batchFunc()
+The batchFunc() 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:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
 af::array filter = randn(1, 5);
@@ -98,15 +87,15 @@ However we would like a vectorized solution. The following syntax begs to be use
 af::array filtered_weights = filter * weights; //fails due to dimension mismatch
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 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 batchFunc() does!
-The signature of the function is:  
+The signature of the function is:
+
+__AFAPI array batchFunc( const array &lhs, const array &rhs, batchFunc_t func );__
 
-__AFAPI array batchFunc( const array &lhs, const array &rhs, batchFunc_t func );__  
+where __batchFunc_t__ is a function pointer of the form:
+__typedef array (*batchFunc_t) ( const array &lhs, const array &rhs );__
 
-where __batchFunc_t__ is a function pointer of the form:  
-__typedef array (*batchFunc_t) ( const array &lhs, const array &rhs );__  
-  
 
-So, to use batchFunc(), we need to provide the function we will be applying as a batch operation. Our final batch call is not much more difficult than the ideal syntax we imagined. 
+So, to use batchFunc(), we need to provide the function we will be applying as a batch operation. Our final batch call is not much more difficult than the ideal syntax we imagined.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
 af::array filtered_weights = batchFunc(filter, weights, operator* );
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/arrayfire.git



More information about the debian-science-commits mailing list