2017-06-12 46 views
0

我对opencl有点新,并且正在尝试学习如何正确使用boost :: compute。请看下面的代码:通过引用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)在程序运行时,我还没有发现任何文件提这个应该怎么实现。

我知道我能做到引用传递(指针实际上,因为它是C99)采用BOOST_COMPUTE_STRINGIZE_SOURCE和指针传递到结构的整个向量,但我想用compute::...功能,因为这些看起来更优雅。

回答

1

如果您定义了BOOST_COMPUTE_DEBUG_KERNEL_COMPILATION宏并且构建OpenCL程序失败,则程序源和构建日志将写入stdout。

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

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