Mali OpenCL SDK v1.1.0
 All Classes Files Functions Variables Macros Pages
Template

A skeleton file that can be used as a starting point for OpenCL development.

Check-list

Check-list for an OpenCL application:

  1. Set up OpenCL environment
  2. Set up memory/data
  3. Execute the kernel instances
  4. After execution

Walkthrough

Set up OpenCL environment

template.cpp uses the common.cpp library to set up the environment.

  1. Create a context

    Create an OpenCL context on the first available platform:

    if (!createContext(&context))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed to create an OpenCL context. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }
  2. Create a command-queue

    Create a command-queue to queue operations on the device:

    if (!createCommandQueue(context, &commandQueue, &device))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed to create the OpenCL command queue. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }
  3. Create a program

    Create an OpenCL program from a given file and compile it:

    if (!createProgram(context, device, "assets/template.cl", &program))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed to create OpenCL program." << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }
  4. Create a kernel

    Create a kernel object for the kernel function template():

    kernel = clCreateKernel(program, "template", &errorNumber);
    if (!checkSuccess(errorNumber))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed to create OpenCL kernel. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }

Set up memory/data

  1. Create memory buffers

    Request memory buffers for any data that you need to access from the device. For more information have a look at the Hello World.

  2. Initialise the input data

    If you need to initialise the data from the CPU side, then you need to:

    1. Map the buffer to a local pointer
    2. Initialise the data using the mapped pointer
    3. Un-map the data

    For more information have a look at the Hello World tutorial.

  3. Set up kernel arguments

    Pass the memory buffers and/or other variables to the kernel as arguments.

    For more information have a look at the Hello World tutorial.

Execute the kernel instances

  1. Define the number of kernel instances

    The globalWorkSize determines how many kernel instances are run.

    const int workDimensions = 1;
    size_t globalWorkSize[workDimensions] = {1};

    For another example have a look at the Hello World tutorial or any of the other tutorials.

  2. Enqueue the kernel

    Enqueue the kernel for execution. To retrieve profiling information, we define a cl_event and pass it to clEnqueueNDRangeKernel().

    /* An event to associate with the kernel. Allows us to retrieve profiling information later. */
    cl_event event = 0;
    if (!checkSuccess(clEnqueueNDRangeKernel(commandQueue, kernel, workDimensions, NULL, globalWorkSize, NULL, 0, NULL, &event)))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed enqueuing the kernel. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }
  3. Wait for kernel execution

    Wait until all the kernel instances have finished executing:

    if (!checkSuccess(clFinish(commandQueue)))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed waiting for kernel execution to finish. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }

    Note: This may not be required depending on the application.

After execution

  1. Print profiling information

    Print the profiling information for the event (queueing, waiting and running time):

    /* Release the event object. */
    if (!checkSuccess(clReleaseEvent(event)))
    {
    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);
    cerr << "Failed releasing the event object. " << __FILE__ << ":"<< __LINE__ << endl;
    return 1;
    }
  2. Retrieve results

    To access the results from the CPU side, you need to:

    1. Map the output buffer to a local pointer
    2. Read the results using the mapped pointer
    3. Un-map the data

    For more information have a look at the Hello World tutorial.

  3. Release OpenCL objects

    Release any OpenCL objects that have been created.

    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);

Running the Sample

This sample does nothing apart from printing profiling information.

  1. From a command prompt in the root of the SDK, run:

    cd samples/template
    make install

    This compiles the template sample code and copies all the files it needs to run to the bin folder in the root directory of the SDK.

  2. Copy this folder to the board.
  3. Navigate to the folder on the board and run the template binary:

    ./template
  4. You should see output similar to:

    Profiling information:
    Queued time: 0.062ms
    Wait time: 0.071535ms
    Run time: 0.001398ms

Find solutions for Common Issues.

More Information

For more information have a look at the code in template.cpp and template.cl.