Do more. Code less. Free software for GPU computing.
<scroll to top>

Graphics - OpenGL Drawing Primitives for GPU Compute

Arrayfire provides several visualization primitives allowing you to explore data at run time using state of the art plotting in OpenGL with minimal impact upon compute time.

Table of contents

Introduction

General purpose computing aside, the GPU is first and foremost a graphics processing machine. Reflecting this reality, ArrayFire ships with a graphics package both with free and commercial versions. Unique to ArrayFire, its graphics engine is designed from the ground-up with GPGPU computing in mind: all primitives draw from memory on the card. Therefore, compute and visualization are both handled by the GPU without any memory transfers between the host CPU and the device. The GPU is left to do what it does best: parallel processing and graphics output while the CPU is left to serial computation and direction of the graphics backend.

Several basic plotting primitives are included with the graphics package including:

Usage

The ArrayFire graphics package is designed as a separate thread that runs along side any GPU compute threads in your application. The programmer is expected to make graphics calls in the GPU compute threads which are then queued up and executed by the graphics thread in first in first out order. As such, most graphics calls are non-blocking and, furthermore, have lower priority than all other GPU compute calls to the rest of ArrayFire. The graphics system's goal is to draw to the screen in the GPU's spare time, leaving the majority of the GPU's time for compute. Thus, some non-blocking commands will be dropped if necessary unless the blocking draw() command is utiilized to force rendering.

The ArrayFire graphics API is divided into two groups: control commands and primitive commands. Control commands instruct the graphics backend to create subfigures (e.g. subfigure), toggle the composition of plots (e.g. keep_on, keep_off), close the current figure window (e.g. close), etc.. Most of the control commands are non-blocking with the exception of draw() and close(). The list of control commands are as follows:

Primitive commands instruct the graphics backend to render data to the screen. All primitive commands are non-blocking. Data associated with each primitive command is copied to a drawing queue along with the primitive. Thus, each primitive command will draw the data that was current at the time of its invocation. However, keep in mind the primitive may be dropped unless a draw() command is utilized to force rendering. Primitive commands include, but are not limited to,

Examples

The following code generates side by side image and line plots of one hundred random samples. Note that draw() is not utilized in this example leaving all graphics commands as non-blocking. Thus, the program generates random samples as quickly as possible and draws the plots as time allows.

    #include <arrayfire.h>
    using namespace af;
    int main(void)
    {
        while (1) {
            array s = randu(10,10);
            subfigure(2,1,1);  imgplot(s);
            subfigure(2,1,2);  plot(s);
        }
        return 0;
    }
simple1.jpg

The following example utilizes the draw() command to block on each render pass. Since draw() is blocking, the loop runs at the same speed as the render loop of the graphics backend: 30 frames per second. The use of draw() does not allow primitives to be dropped.

    #include <arrayfire.h>
    using namespace af;
    int main(void)
    {
        while (1) {
            array s = randu(10,10);
            subfigure(2,1,1);  imgplot(s);
            subfigure(2,1,2);  plot(s);
            draw();
        }
        return 0;
    }

The following example utilizes the keep_on() and keep_off() commands to compose an image plot and a line plot. Note that no blocking graphics routines are used, necessitating the second to last line of the main function where we block until the user presses a key.

    #include <arrayfire.h>
    using namespace af;
    int main(void)
    {
        imgplot(randu(10, 10));
        keep_on();
        plot(seq(1,10));
        keep_off();
        palette("gray");
        char t; std::cin.get(t);  // wait for keypress
        return 0;
    }
simple2.jpg

See also:

Notes:

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines