Appendix A - Getting Started

 

A.1 Getting Started

The purpose of this section is to give a headstart into GPU programming using the Python programming language. Not expecting of being comprehensive of all the features involved into GPU programming
this document aims instead at introducing the novice programmer to the graphics acceleration world abstracting from low-level details peculiar to languages as GLSL or HLSL.

pipelineOGL

Figure A.1: Graphics Processing Pipeline

A.1.1 The Rendering Pipeline

Rendering is the conversion of a scene into an image. The rendering pipeline or graphics pipeline in computer graphics is a conceptual representation of the stages through which a certain representation of a 2D or 3D scene goes through to produce as output the final 2D raster image. Each graphics packages has its own rendering pipeline in terms of 2D or 3D primitives representation and sequence of processes applied to them. Graphics rendering pipeline are commonly represented as state-diagram, where each state refers to the sequence of transformations applied to the input data. Fig. A.1 represents an abstraction of a rendering pipeline diagram. Input data to a graphics pipeline are generally vertices together with their respective set of attributes such as position in space, colour, normals and texture coordinates. Each transformation step within the pipeline vertices and their abstract attributes are mathematically processed to generate physical screen coordinates and display values. In old graphics card each stage of the pipeline was implemented as fixed function, i.e. the algorithms (shaders) used to perform the transformations were decided at the card manufacturing stage and could not be altered afterwards. The novelty introduced by graphics accelerators was to give the programmer access to two of the graphics pipeline stages: vertex transformation stage and fragment transformation stage. The rendering pipeline has then become programmable, piece of code used to apply transformation effects on the input data would be called shaders.

visualpipeline

Figure A.2: Vertices and Fragments transformation stages.

A.1.2 Vertex Shader

The vertex processor is a programmable unit that operates on incoming vertices and their associated data A.2. Vertex shaders are set of functions used to transform each abstract vertex position in world space to the 2D coordinate system at which it appears on the screen. Vertex shaders run on the vertex processor.

A.1.3 Fragment Shader

The fragment processor is a programmable unit that operates on incoming fragments and their associated data A.2. Fragments shaders are set of functions used to transform each abstract vertex attribute such as colour, normal, texture value to the display colour system. Fragment shaders are typically used to mimic effects such as scene lighting and colour toning on a per pixel base, for this reason the are often referred to as pixel shaders. Fragment shaders run on the fragment processor.

A.1.4 Programming the GPU with Python

The way to program the GPU is via vertex and fragment shaders creation. Several API exists to ease the process such as GLSL, HLSL, Cg and many more. In this section we will experiment with PyGPU [13] a Python based API for GPU programming. PyGPU runs as initially born as a domain specific language for image processing, it now features a compiler that generates code executable on the GPU. PyGPU runs as an embedded language inside Python and as such it inherits the functionality and syntax of the host language. It interfaces with the graphics card through a set of extension packages: NumPy [14] an extension to the Python language for scientific computing, Pygame [15] a Python API for game development, PyGlew [16] a Python binding for the OpenGL Extension Wrangler (GLEW) and PyCg [17] a Python binding for the NVIDIA Cg language [18] which makes PyGPU bounded to NVIDIA graphics card. To start experimenting download the aforementioned packages and install them on your PC, refer to http://www.cs.lth.se/home/Calle\_Lejdfors/pygpu/ for instruction on how to download and install PyGPU and its complements.

A.1.4.1 PyGPU Shader Example

PyGPULena

Figure A.3: Sobel PyGPU Edge Detector applied to the Lena image.

The compiler plays a major role in PyGPU, it allows Python code to be compiled into native code executable on the graphics hardware. The example we show is taken from [13]. Edge detections is a problem of fundamental importance in image processing as edges characterize boundaries between objects within an image. Edges are parts of an image with high intensity contrast, i.e. the image brightness changes sharply. Edge detection methods can be grouped into two main categories: gradient based and Laplacian. The Sobel edge detection algorithm belongs to the first group. The Sobel operator performs a 2-D spatial gradient measurement of the image intensity at each point (or pixel). The operator uses a pair of 3x3 convolution masks (see Figure A.4), or kernels, to estimate gradients in the x-direction and y-direction respectively. Convolution masks are usually much smaller than the actual image therefore they slid over the image manipulating squares of pixel at a time.

SobelOp

Figure A.4: Sobel Convolution Kernels

The following function definition implements a gradient based edge detector algorithm in Python:

def edgeDetect(kernel, im=Image, p=Position):
    Gx = convolve(kernel, im, p)
    Gy = convolve(transpose(kernel), im, p)
    return sqrt(Gx**2 + Gy**2)

edgeDetect applies a pair of convolution kernels in the x and y direction and returns the magnitude of the image gradient. The edge detection algorithm is a multi-step process therefore can be easily implemented on the GPU as a sequence of filtering operations to take advantage of the graphics accelerator capabilities. We can then specialize the edge detection function and use the PyGPU compiler to translate it into native GPU code:

sobelEdgeDetGPU = pygpu.compile(edgeDetect, kernel=sobelKernel)

The function returned by the compiler is what would be called a shader, it runs entirely on the GPU. An example of the sobelEdgeDetGPU applied to the famous Lena image is shown in Figure A.3. For more insights into how the PyGPU compiler is implemented refer to [13] and [19].

Resources for GPU programming with Python are rather limited an interesting project worth to look at is PYGWA [20] an extended GPGPU library for Python an extended GPGPU library for Python.

A.2 Acknowledgments

We thank Dr. Joachim Diepstraten for all the helpful suggestions and material provided.
This report was produced with funding from VizNET, the UK visualization support network.


  1. C. Lejdfors and L. Ohlsson. Implementing an embedded gpu language by combining translation and generation. In SAC '06: Proceedings of the 2006 ACM symposium on Applied computing, pages 1610-1614, New York, NY, USA, 2006. ACM.
  2. Numpy, jan 2009.
  3. Pygame, jan 2009.
  4. Pyglew, jan 2009.
  5. Pycg, jan 2009.
  6. The NVIDIA Cg toolkit, jan 2009.
  7. Pygpu, jan 2009.
  8. Pygwa, jan 2009.