PrevUpHomeNext

Tutorial

Hello World
Transferring Data
Transforming Data
Vector Data Types

The hello world example gives a simple application that prints the name of the default GPU compute device on the system.

Compute devices are represented with the device class.

#include <iostream>
#include <boost/compute.hpp>

int main()
{
    // get the default GPU device
    boost::compute::device gpu =
        boost::compute::system::default_gpu_device();

    // print the GPU's name
    std::cout << "hello from " << gpu.name() << std::endl;

    return 0;
}

Before any computation occurs, data must be transferred from the host to the compute device. The generic copy() function provides a simple interface for transfering data and the generic vector<T> class provides a container for storing data on a compute device.

The following example shows how to transfer data from an array on the host to a vector<T> on the device and then back to a separate std::vector<T> on the host. At the end of the example both host_array and host_vector contain the same values which were copied through the memory on the compute device.

#include <vector>
#include <boost/compute.hpp>

int main()
{
    // create data array on host
    int host_data[] = { 1, 3, 5, 7, 9 };

    // create vector on device
    boost::compute::vector<int> device_vector(5);

    // copy from host to device
    boost::compute::copy(host_data,
                         host_data + 5,
                         device_vector.begin());

    // create vector on host
    std::vector<int> host_vector(5);

    // copy data back to host
    boost::compute::copy(device_vector.begin(),
                         device_vector.end(),
                         host_vector.begin());

    return 0;
}

The following example shows how to calculate the square-root of a vector of floats on a compute device using the transform() function.

#include <vector>
#include <algorithm>
#include <boost/compute.hpp>

int main()
{
    // generate random data on the host
    std::vector<float> host_vector(10000);
    std::generate(host_vector.begin(), host_vector.end(), rand);

    // create a vector on the device and transfer data from the host
    boost::compute::vector<float> device_vector = host_vector;

    // calculate sqrt of each element in-place
    boost::compute::transform(device_vector.begin(),
                              device_vector.end(),
                              device_vector.begin(),
                              boost::compute::sqrt<float>());

    // copy values back to the host
    boost::compute::copy(device_vector.begin(),
                         device_vector.end(),
                         host_vector.begin());

    return 0;
}

In addition to the built-in scalar types (e.g. int and float), OpenCL also provides vector data types (e.g. int2 and vector4). These can be used with the Boost Compute library on both the host and device.

Boost.Compute provides typedefs for these types which take the form: boost::compute::scalarN_ where scalar is a scalar data type (e.g. int, float, char) and N is the size of the vector. Supported vector sizes are: 2, 4, 8, and 16.

The following example shows how to transfer a set of 3D points stored as an array of floats on the host the device and then calculate the sum of the point coordinates using the accumulate() function. The sum is transferred to the host and the centroid computed by dividing by the total number of points.

Note that even though the points are in 3D, they are stored as float4 due to OpenCL's alignment requirements.

#include <iostream>
#include <boost/compute.hpp>

// the point centroid example calculates and displays the
// centroid of a set of 3D points stored as float4's
int main()
{
    using boost::compute::float4_;

    // point coordinates
    float points[] = { 1.0f, 2.0f, 3.0f, 0.0f,
                       -2.0f, -3.0f, 4.0f, 0.0f,
                       1.0f, -2.0f, 2.5f, 0.0f,
                       -7.0f, -3.0f, -2.0f, 0.0f,
                       3.0f, 4.0f, -5.0f, 0.0f };

    // create vector for five points
    boost::compute::vector<float4_> vector(5);

    // copy point data to the device
    boost::compute::copy(
        reinterpret_cast<float4_ *>(points),
        reinterpret_cast<float4_ *>(points) + 5,
        vector.begin()
    );

    // calculate sum
    float4_ sum = boost::compute::accumulate(vector.begin(),
                                             vector.end(),
                                             float4_(0, 0, 0, 0));

    // calculate centroid
    float4_ centroid;
    for(size_t i = 0; i < 3; i++){
        centroid[i] = sum[i] / 5.0f;
    }

    // print centroid
    std::cout << "centroid: " << centroid << std::endl;
}


PrevUpHomeNext