Skip to content

Commit d8b6246

Browse files
committed
[Docs] Update Forge page
* Clean up the intro to the Forge page * Change order of items in the side menu
1 parent b3b42c6 commit d8b6246

2 files changed

Lines changed: 2 additions & 161 deletions

File tree

‎docs/layout.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
<tab type="user" url="\ref matrixmanipulation" visible="yes" title="Array and Matrix Manipulation"/>
1313
<tab type="user" url="\ref interop_cuda" visible="yes" title="CUDA Interoperability"/>
1414
<tab type="user" url="\ref interop_opencl" visible="yes" title="OpenCL Interoperability"/>
15+
<tab type="user" url="\ref forge_visualization" visible="yes" title="Visualizing arrays with Forge"/>
1516
<tab type="user" url="\ref unifiedbackend" visible="yes" title="Unified Backend"/>
16-
<tab type="user" url="\ref forge_visualization" visible="yes" title="Forge Visualization"/>
1717
<tab type="user" url="\ref indexing" visible="yes" title="Indexing"/>
1818
<tab type="user" url="\ref timing" visible="yes" title="Timing ArrayFire"/>
1919
<tab type="user" url="\ref configuring_environment" visible="yes" title="Configuring ArrayFire Environment"/>

‎docs/pages/forge_visualization.md‎

Lines changed: 1 addition & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1 @@
1-
Visualizing af::array with Forge {#forge_visualization}
2-
===================
3-
4-
Arrayfire as a library aims to provide a robust and easy to use platform for
5-
high-performance, parallel and GPU computing.
6-
7-
[TOC]
8-
9-
The goal of [Forge](https://github.com/arrayfire/forge), an OpenGL visualization
10-
library, is to provide equally robust visualizations that are interoperable
11-
between Arrayfire data-structures and an OpenGL context.
12-
13-
Arrayfire provides wrapper functions that are designed to be a simple interface
14-
to visualize af::arrays. These functions perform various interop tasks. One in
15-
particular is that instead of wasting time copying and reformatting data from
16-
the GPU to the host and back to the GPU, we can draw directly from GPU-data to
17-
GPU-framebuffers! This saves 2 memory copies.
18-
19-
Let's see exactly what visuals we can illuminate with forge and how Arrayfire
20-
anneals the data between the two libraries.
21-
22-
# Setup {#setup}
23-
Before we can call Forge functions, we need to set up the related "canvas" classes.
24-
Forge functions are tied to the af::Window class. First let's create a window:
25-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
26-
const static int width = 512, height = 512;
27-
af::Window window(width, height, "2D plot example title");
28-
29-
do{
30-
31-
//drawing functions here
32-
33-
} while( !window.close() );
34-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35-
36-
We also added a drawing loop, so now we can use Forge's drawing functions to
37-
draw to the window.
38-
The drawing functions present in Forge are listed below.
39-
40-
# Rendering Functions {#render_func}
41-
42-
Documentation for rendering functions can be found [here](\ref gfx_func_draw).
43-
44-
## Image {#image}
45-
The af::Window::image() function can be used to plot grayscale or color images.
46-
To plot a grayscale image a 2d array should be passed into the function.
47-
Let's see this on a static noise example:
48-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
49-
array img = constant(0, width, height); //make a black image
50-
array random = randu(width, height); //make random [0,1] distribution
51-
img(random > 0.5) = 1; //set all pixels where distribution > 0.5 to white
52-
53-
window.image(img);
54-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55-
<img src="gfx_docs_images/noise.png" alt="Forge image plot of noise" width="20%" />
56-
Tweaking the previous example by giving our image a depth of 3 for the RGB values
57-
allows us to generate colorful noise:
58-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
59-
array img = 255 * randu(width, height, 3); //make random [0, 255] distribution
60-
window.image( img.as(u8) );
61-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62-
<img src="gfx_docs_images/color_noise.png" alt="Forge image plot of color noise" width="20%" />
63-
Note that Forge automatically handles any af::array type passed from Arrayfire.
64-
In the first example we passed in an image of floats in the range [0, 1].
65-
In the last example we cast our array to an unsigned byte array with the range
66-
[0, 255]. The type-handling properties are consistent for all Forge drawing functions.
67-
68-
## Plot {#plot}
69-
The af::Window::plot() function visualizes an array as a 2d-line plot. Let's see
70-
a simple example:
71-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
72-
array X = seq(-af::Pi, af::Pi, 0.01);
73-
array Y = sin(X);
74-
window.plot(X, Y);
75-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76-
77-
<img src="gfx_docs_images/sin_plot.png" alt="Forge 2d line plot of sin() function" width="30%" />
78-
The plot function has the signature:
79-
80-
> **void plot( const array &X, const array &Y, const char * const title = NULL );**
81-
82-
Both the x and y coordinates of the points are required to plot. This allows for
83-
non-uniform, or parametric plots:
84-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
85-
array t = seq(0, 100, 0.01);
86-
array X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));
87-
array Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));
88-
window.plot(X, Y);
89-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90-
91-
<img src="gfx_docs_images/butterfly_plot.png" alt="Forge 2d line plot of butterfly function" width="30%" />
92-
93-
## Plot3 {#plot3}
94-
The af::Window::plot3() function will plot a curve in 3d-space.
95-
Its signature is:
96-
> **void plot3 (const array &in, const char * title = NULL);**
97-
The input array expects xyz-triplets in sequential order. The points can be in a
98-
flattened one dimensional (*3n x 1*) array, or in one of the (*3 x n*), (*n x 3*) matrix forms.
99-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
100-
array Z = seq(0.1f, 10.f, 0.01);
101-
array Y = sin(10 * Z) / Z;
102-
array X = cos(10 * Z) / Z;
103-
104-
array Pts = join(1, X, Y, Z);
105-
//Pts can be passed in as a matrix in the from n x 3, 3 x n
106-
//or in the flattened xyz-triplet array with size 3n x 1
107-
window.plot3(Pts);
108-
//both of the following are equally valid
109-
//window.plot3(transpose(Pts));
110-
//window.plot3(flat(Pts));
111-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112-
<img src="gfx_docs_images/spiral_plot3.png" alt="Forge 3d line plot" width="40%" />
113-
114-
## Histogram {#histogram}
115-
The af::Window::hist() function renders an input array as a histogram.
116-
In our example, the input array will be created with Arrayfire's histogram()
117-
function, which actually counts and bins each sample. The output from histogram()
118-
can directly be fed into the af::Window::hist() rendering function.
119-
120-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
121-
const int BINS = 128; SAMPLES = 9162;
122-
array norm = randn(SAMPLES);
123-
array hist_arr = histogram(norm, BINS);
124-
125-
win.hist(hist_arr, 0, BINS);
126-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127-
In addition to the histogram array with the number of samples in each bin, the
128-
af::Window::hist() function takes two additional parameters -- the minimum and
129-
maximum values of all datapoints in the histogram array. This effectively sets
130-
the range of the binned data. The full signature of af::Window::hist() is:
131-
> **void hist(const array & X, const double minval, const double maxval, const char * const title = NULL);**
132-
<img src="gfx_docs_images/norm_histogram.png" alt="Forge 3d scatter plot" width="40%" />
133-
134-
135-
## Surface {#surface}
136-
The af::Window::surface() function will plot af::arrays as a 3d surface.
137-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
138-
array Z = randu(21, 21);
139-
window.surface(Z, "Random Surface"); //equal to next function call
140-
//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, "Random Surface");
141-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142-
<img src="gfx_docs_images/rand_surface.png" alt="Forge random surface plot" width="30%" />
143-
There are two overloads for the af::Window::surface() function:
144-
> **void surface (const array & S, const char * const title )**
145-
> // Accepts a 2d matrix with the z values of the surface
146-
147-
> **void surface (const array &xVals, const array &yVals, const array &S, const char * const title)**
148-
> // accepts additional vectors that define the x,y coordinates for the surface points.
149-
150-
The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size **m x n**:
151-
1. Short vectors defining the spacing along each axis. Vectors will have sizes **m x 1** and **n x 1**.
152-
2. Vectors containing the coordinates of each and every point.
153-
Each of the vectors will have length **mn x 1**.
154-
This can be used for completely non-uniform or parametric surfaces.
155-
156-
# Conclusion {#conclusion}
157-
There is a fairly comprehensive collection of methods to visualize data in Arrayfire.
158-
Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire
159-
functions not only make visualizations as simple as possible, but keep them as
160-
robust as the rest of the Arrayfire library.
1+
robust as the rest of the ArrayFire library.

0 commit comments

Comments
 (0)