Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Advanced Topics

Boost , Chapter 1. Boost.Compute , Chapter 1. Boost.Compute

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Следующие темы показывают расширенные возможности библиотеки Boost Compute.

В дополнение к встроенным скалярным типам (например,<int>и<float>), OpenCL также предоставляет векторные типы данных (например,<int2>и<vector4>). Они могут использоваться с библиотекой Boost Compute как на хосте, так и на устройстве.

Повышаю. Вычисление предоставляет типдефы для этих типов, которые принимают форму:<boost::compute::scalarN_>, где<scalar>является скалярным типом данных (например,<int>,<float>,<char>) и<N>является размером вектора. Поддерживаемые векторные размеры: 2, 4, 8 и 16.

Следующий пример показывает, как передать набор 3D точек, хранящихся в виде массива<float>s на хосте устройства, а затем вычислить сумму координат точек с помощью функции<accumulate()>. Сумма переносится на хост и вычисляется центроидом путем деления на общее количество точек.

Обратите внимание, что даже если точки находятся в 3D, они хранятся как<float4>из-за требований выравнивания OpenCL.

#include <iostream>
#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/algorithm/accumulate.hpp>
#include <boost/compute/container/vector.hpp>
#include <boost/compute/types/fundamental.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_;
    // get default device and setup context
    compute::device device = compute::system::default_device();
    compute::context context(device);
    compute::command_queue queue(context, device);
    // 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, context);
    // copy point data to the device
    compute::copy(
        reinterpret_cast<float4_ *>(points),
        reinterpret_cast<float4_ *>(points) + 5,
        vector.begin(),
        queue
    );
    // calculate sum
    float4_ sum = compute::accumulate(
        vector.begin(), vector.end(), float4_(0, 0, 0, 0), queue
    );
    // 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;
    return 0;
}

Среда выполнения OpenCL и библиотека Boost Compute обеспечивают ряд встроенных функций, таких как sqrt() и dot(), но во многих случаях этого недостаточно для решения проблемы.

Библиотека Boost Compute предоставляет несколько различных способов создания пользовательских функций, которые могут быть переданы предоставленным алгоритмам, таким как<transform()>и<reduce()>.

Самый простой способ - предоставить исходный код для функции:

boost::compute::function<int (int)> add_four =
    boost::compute::make_function_from_source<int (int)>(
        "add_four",
        "int add_four(int x) { return x + 4; }"
    );
boost::compute::transform(input.begin(), input.end(), output.begin(), add_four, queue);

Это также можно сделать более кратко, используя макрос<BOOST_COMPUTE_FUNCTION>:

BOOST_COMPUTE_FUNCTION(int, add_four, (int x),
{
    return x + 4;
});
boost::compute::transform(input.begin(), input.end(), output.begin(), add_four, queue);

Также см.«Таможенные функции OpenCL на C++ с Boost.Compute»для более подробной информации.

Повышаю. Вычисление обеспечивает макрос<BOOST_COMPUTE_ADAPT_STRUCT>, который позволяет обертывать и использовать структуру / класс C++ в OpenCL.

Хотя сама OpenCL изначально не поддерживает сложные типы данных, библиотека Boost Compute предоставляет их.

Для использования комплексных значений сначала включите следующий заголовок:

#include <boost/compute/types/complex.hpp>

Вектор комплексных значений может быть создан таким образом:

// create vector on device
boost::compute::vector<std::complex<float> > vector;
// insert two complex values
vector.push_back(std::complex<float>(1.0f, 3.0f));
vector.push_back(std::complex<float>(2.0f, 4.0f));

Структура выражения лямбда позволяет определять функции и предикаты на сайте вызова алгоритма.

Ламбда-выражения используют заполнители<_1>и<_2>для обозначения аргументов. Следующие декларации приведут держателей лямбда в текущую область применения:

using boost::compute::lambda::_1;
using boost::compute::lambda::_2;

Следующие примеры показывают, как использовать выражения лямбда вместе с Boost. Вычислите алгоритмы для выполнения более сложных операций на устройстве.

Чтобы подсчитать число нечетных значений в векторе:

boost::compute::count_if(vector.begin(), vector.end(), _1 % 2 == 1, queue);

Умножить каждое значение в векторе на три и вычесть четыре:

boost::compute::transform(vector.begin(), vector.end(), vector.begin(), _1 * 3 - 4, queue);

Выражения лямбда также могут использоваться для создания функций и объектов:

boost::compute::function<int(int)> add_four = _1 + 4;

Основным узким местом производительности в приложениях GPGPU является передача памяти. Это может быть облегчено путем перекрытия передачи памяти с вычислениями. Библиотека Boost Compute обеспечивает функцию<copy_async()>, которая выполняет асинхронную передачу памяти между хостом и устройством.

Например, инициировать копию с хоста на устройство и затем выполнять другие действия:

// data on the host
std::vector<float> host_vector = ...
// create a vector on the device
boost::compute::vector<float> device_vector(host_vector.size(), context);
// copy data to the device asynchronously
boost::compute::future<void> f = boost::compute::copy_async(
    host_vector.begin(), host_vector.end(), device_vector.begin(), queue
);
// perform other work on the host or device
// ...
// ensure the copy is completed
f.wait();
// use data on the device (e.g. sort)
boost::compute::sort(device_vector.begin(), device_vector.end(), queue);

Например, для измерения времени копирования вектора данных с хоста на устройство:

#include <vector>
#include <cstdlib>
#include <iostream>
#include <boost/compute/event.hpp>
#include <boost/compute/system.hpp>
#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/async/future.hpp>
#include <boost/compute/container/vector.hpp>
namespace compute = boost::compute;
int main()
{
    // get the default device
    compute::device gpu = compute::system::default_device();
    // create context for default device
    compute::context context(gpu);
    // create command queue with profiling enabled
    compute::command_queue queue(
        context, gpu, compute::command_queue::enable_profiling
    );
    // generate random data on the host
    std::vector<int> host_vector(16000000);
    std::generate(host_vector.begin(), host_vector.end(), rand);
    // create a vector on the device
    compute::vector<int> device_vector(host_vector.size(), context);
    // copy data from the host to the device
    compute::future<void> future = compute::copy_async(
        host_vector.begin(), host_vector.end(), device_vector.begin(), queue
    );
    // wait for copy to finish
    future.wait();
    // get elapsed time from event profiling information
    boost::chrono::milliseconds duration =
        future.get_event().duration<boost::chrono::milliseconds>();
    // print elapsed time in milliseconds
    std::cout << "time: " << duration.count() << " ms" << std::endl;
    return 0;
}

Библиотека Boost Compute предназначена для легкого взаимодействия с OpenCL API. Все завернутые классы имеют операторы преобразования в свои основные типы OpenCL, что позволяет передавать их непосредственно в функции OpenCL.

Например,

// create context object
boost::compute::context ctx = boost::compute::default_context();
// query number of devices using the OpenCL API
cl_uint num_devices;
clGetContextInfo(ctx, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &num_devices, 0);
std::cout << "num_devices: " << num_devices << std::endl;


PrevUpHomeNext

Статья Advanced Topics раздела Chapter 1. Boost.Compute Chapter 1. Boost.Compute может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Boost.Compute ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 05:58:57/0.0097579956054688/1