The hello world example gives a simple application that prints the name of the default compute device on the system.
Compute devices are represented with the device
class.
#include <iostream> #include <boost/compute/device.hpp> #include <boost/compute/system.hpp> namespace compute = boost::compute; int main() { // get the default device compute::device device = compute::system::default_device(); // print the device's name std::cout << "hello from " << device.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/algorithm/copy.hpp> #include <boost/compute/container/vector.hpp> namespace compute = boost::compute; int main() { // create data array on host int host_data[] = { 1, 3, 5, 7, 9 }; // create vector on device compute::vector<int> device_vector(5); // copy from host to device 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 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/algorithm/transform.hpp> #include <boost/compute/container/vector.hpp> #include <boost/compute/functional/math.hpp> namespace compute = boost::compute; 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 compute::vector<float> device_vector = host_vector; // calculate sqrt of each element in-place compute::transform(device_vector.begin(), device_vector.end(), device_vector.begin(), compute::sqrt<float>()); // copy values back to the host 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/algorithm/copy.hpp> #include <boost/compute/algorithm/accumulate.hpp> #include <boost/compute/container/vector.hpp> #include <boost/compute/types/builtin.hpp> namespace compute = boost::compute; // the point centroid example calculates and displays the // centroid of a set of 3D points stored as float4's int main() { using 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 compute::vector<float4_> vector(5); // copy point data to the device compute::copy( reinterpret_cast<float4_ *>(points), reinterpret_cast<float4_ *>(points) + 5, vector.begin() ); // calculate sum float4_ sum = 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; }