0

カーネルの呼び出しに問題があります。私のコードは次のようになります。

std::vector<cl::Event> events;
...

queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent);
events.push_back(arrayEvent);

queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond, this->arraySecond, NULL, &arraySecondEvent);
events.push_back(arraySecondEvent);

kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);

そして、それを実行すると、カーネルコード内には入りませんが、「make_kernel」の呼び出しを次のように変更すると:

kernel(cl::EnqueueArgs(queue, arraySecondEvent, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);

カーネル内に入りますが、「arrayFirst」のメモリが正しく割り当てられているかどうかはわかりません。OpenCl 1.2 Wrapper のドキュメントを確認したところ、呼び出しは次のようになっていることがわかりました。

cl::EnqueueArgs::EnqueueArgs(CommandQueue &queue,
const VECTOR_CLASS<Event> &events, NDRange offset, NDRange global,
NDRange local) //page 42

しかし、イベントベクターのアドレスを渡そうとすると、次の引数を持つ適切なメソッドがないというコンパイルエラーが発生します..

エラー:

error: no instance of constructor "cl::EnqueueArgs::EnqueueArgs" matches the argument list
            argument types are: (cl::CommandQueue, std::vector<cl::Event, std::allocator<cl::Event>> *, cl::NDRange, cl::NDRange)
              valueOfImageKernel(cl::EnqueueArgs(valueOfImageQueue, &events, cl::NDRange(512), cl::NDRange(128)),

誰が私が間違っているのか分かりますか?

4

2 に答える 2

1

必要のない以下の行が問題を引き起こしているようです: queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent); 実際にそこに書き込むものがある場合、バッファーに書き込むために呼び出す必要がありますが、ここではそうではありません。

PHIでテストされた完全な動作例の下(わかりやすくするためにエラー処理は省略されています):

#include <iostream>
#include <vector>
#include <string>

#include <CL/cl.hpp>

int main()
{
    const char *kernel_str{
        "kernel void k1(global int *data1, global int *data2){"
        " int local_id = get_local_id(0);"
        " data1[local_id] = data2[local_id] + data2[local_id];"
        "}" };

    cl_int err = CL_SUCCESS;

    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);
    cl::Platform plat;
    for (auto &p : platforms)
    {
        std::vector<cl::Device> devices;
        p.getDevices(CL_DEVICE_TYPE_ACCELERATOR, &devices);
        if (!devices.empty())
        {
            plat = p;
            break;
        }
    }
    if (plat() == 0)
    {
        std::cout << "No OpenCL platform found.";
        return -1;
    }

    cl_context_properties properties[] =
    { CL_CONTEXT_PLATFORM, (cl_context_properties)(plat)(), 0 };
    cl::Context context(CL_DEVICE_TYPE_ACCELERATOR, properties);

    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();

    cl::Program::Sources source(1, std::make_pair(kernel_str, strlen(kernel_str)));
    cl::Program program = cl::Program(context, source);
    err = program.build(devices);

    cl::CommandQueue queue(context, devices[0], 0, &err);

    size_t sizeOfArray = 512, sizeOfArraySecond = 512;
    std::vector<int> varrayFirst(sizeOfArray);
    std::vector<int> varraySecond(sizeOfArraySecond);
    for (size_t x = 0; x < sizeOfArraySecond; ++x)
        varraySecond[x] = x;

    cl::Buffer arrayFirst(context, CL_MEM_WRITE_ONLY, sizeOfArray*sizeof(varrayFirst[0]));
    cl::Buffer arraySecond(context, CL_MEM_READ_ONLY, sizeOfArraySecond*sizeof(varraySecond[0]));

    cl::Event arraySecondEvent;

    std::vector<cl::Event> events;
    err = queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond*sizeof(varraySecond[0]), &varraySecond[0], NULL, &arraySecondEvent);
    events.push_back(arraySecondEvent);

    cl::make_kernel<cl::Buffer&, cl::Buffer&> kernel(program, "k1");

    cl::Event ev = kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);

    std::vector<cl::Event> evs(1, ev);

    err = queue.enqueueReadBuffer(arrayFirst, CL_TRUE, 0, sizeOfArray*sizeof(varrayFirst[0]), &varrayFirst[0], &evs); // final blocking read

    std::cout << "Outputting first 10 values: " << std::endl;
    for (int x = 0; x < 10; ++x)
        std::cout << varrayFirst[x] << ", ";
    std::cout << std::endl;

    return 0;
}

出力:

Outputting first 10 values:
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
于 2015-11-01T21:10:25.507 に答える
0

イベントのコレクションは正しく、カーネル呼び出しも正しいです。ここで問題は...カーネルがブロックされていると確信していますか? 起動が遅いだけかもしれません。

event.finish()カーネルイベントで確認します。アプリがデッドロックした場合、イベントに問題があります。

それ以外の場合は、カーネルが実行される前に実行可能ファイルが終了する可能性があります (最初のバッファー コピーを待機しているため、時間がかかります)。そのため、カーネルが printfs するときにアプリが既にクリーンアップしているため、ログは表示されません。

さらに、イベントのすべてのコードを追加できれば、デバッグに役立つ可能性があります。イベント配列の完全なライフサイクルを見ていないためです。

于 2015-11-02T14:41:29.480 に答える