私は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
は値によって構造体を渡し、それらを処理して元に戻します。
プログラムが実行されると、私はこれを達成する方法を言及するすべての文書を発見していないとき、私はcompute::for_each
でコメントアウトBOOST_COMPUTE_CLOSUREに示すように参照することによってこれらを渡したいと思いますが、カーネルがコンパイルする(Build Program Failure
を)失敗しました。 を使って参照渡し(実際にはポインタはC99なので)、構造体のベクトル全体にポインタを渡すことで実現できますが、compute::...
の関数をもっとエレガントに見せたいと思います。