【问题标题】:Pass a vector of custom structs by reference to a boost::compute closure or function通过引用 boost::compute 闭包或函数来传递自定义结构的向量
【发布时间】:2017-11-14 01:45:19
【问题描述】:

我对 opencl 有点陌生,正在尝试学习正确使用 boost::compute。考虑以下代码:

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

const cl_int cell_U_size{ 4 };

#pragma pack (push,1)
struct Cell
{
    cl_double U[cell_U_size];
};
#pragma pack (pop)

BOOST_COMPUTE_ADAPT_STRUCT(Cell, Cell, (U));

int main(int argc, char* argv[])
{
    using namespace boost;
    auto device = compute::system::default_device();
    auto context = compute::context(device);
    auto queue = compute::command_queue(context, device);

    std::vector<Cell> host_Cells;
    host_Cells.reserve(10);
    for (auto j = 0; j < host_Cells.capacity(); ++j) {
        host_Cells.emplace_back(Cell());
        for (auto i = 0; i < cell_U_size; ++i) {
            host_Cells.back().U[i] = static_cast<cl_double>(i+j);
        }
    }
    std::cout << "Before:\n";
    for (auto const& hc : host_Cells) {
        for (auto const& u : hc.U)
            std::cout << " " << u;
        std::cout << "\n";
    }
    compute::vector<Cell> device_Cells(host_Cells.size(), context);
    auto f = compute::copy_async(host_Cells.begin(), host_Cells.end(), device_Cells.begin(), queue);
    try {
        BOOST_COMPUTE_CLOSURE(Cell, Step1, (Cell cell), (cell_U_size), {
            for (int i = 0; i < cell_U_size; ++i) {
                cell.U[i] += 1.0;
            }
            return cell;
        });
        f.wait(); // Wait for data to finish being copied
        compute::transform(device_Cells.begin(), device_Cells.end(), device_Cells.begin(), Step1, queue);

        //BOOST_COMPUTE_CLOSURE(void, Step2, (Cell &cell), (cell_U_size), {
        //  for (int i = 0; i < cell_U_size; ++i) {
        //      cell.U[i] += 1.0;
        //  }
        //});
        //compute::for_each(device_Cells.begin(), device_Cells.end(), Step2, queue);

        compute::copy(device_Cells.begin(), device_Cells.end(), host_Cells.begin(), queue);
    }
    catch (std::exception &e) {
        std::cout << e.what() << std::endl;
        throw;
    }
    std::cout << "After:\n";
    for (auto const& hc : host_Cells) {
        for (auto const& u : hc.U)
            std::cout << " " << u;
        std::cout << "\n";
    }
}

我有一个要在 GPU 上处理的自定义结构向量(实际上比此处显示的要复杂得多)。在未注释的 BOOST_COMPUTE_CLOSURE 中,compute::transform 按值传递结构,处理它们,然后将它们复制回来。

我想通过引用来传递这些,如注释掉的 BOOST_COMPUTE_CLOSURE 和 compute::for_each 所示,但是当程序运行时内核无法编译 (Build Program Failure),我还没有找到任何文档提到这应该如何实现。

我知道我可以通过使用 BOOST_COMPUTE_STRINGIZE_SOURCE 并将指针传递给整个结构向量来实现按引用传递(实际上是指针,因为它是 C99),但我想使用 compute::... 函数,因为这些看起来更优雅。

【问题讨论】:

    标签: c++ opencl pass-by-reference boost-compute


    【解决方案1】:

    如果你定义了BOOST_COMPUTE_DEBUG_KERNEL_COMPILATION宏并且构建OpenCL程序失败,程序源和构建日志将被写入标准输出。

    您不能在 OpenCL C 中通过引用传递,而您正试图在 BOOST_COMPUTE_CLOSURE 中执行此操作。我了解您希望将 __global 指针传递给您的闭包并修改全局内存中变量的值,而不是该值的本地副本。我认为 Boost.Compute 不支持它,因为在 for_each(和其他算法)中,Boost.Compute 总是将值传递给您的函数/闭包。

    当然,您始终可以实施解决方法 - 添加一元 &amp; 运算符,或实施自定义设备迭代器。但是,在给出的示例中,它只会降低性能,因为它会导致非合并的内存读取和写入。如果您有非常复杂的结构数组 (AoS),请尝试更改它的数组结构 (SoA) 或/并破坏您的结构。

    【讨论】:

      猜你喜欢
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      • 2020-12-07
      • 2019-07-05
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多