5

CのホストコードからOpenCLカーネル関数にベクトル型(uint8)パラメーターを渡すのに問題があります。

ホストでは、データを配列に入れています。

cl_uint dataArr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

(私の実際のデータは[1、8]だけではありません。これは、説明を簡単にするためです。)

次に、データをバッファに転送してカーネルに渡します。

cl_mem kernelInputData = clCreateBuffer(context,
    CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)*8, dataArr, NULL);

次に、このバッファをカーネルに渡します。

clSetKernelArg(kernel, 0, sizeof(cl_mem), &kernelInputData);

そして、カーネル関数のシグネチャは次のようになります。

kernel void kernelFunction(constant uint8 *vectorPtr)

ただし、カーネルはへのポインタから正しい入力データを取得していないようですkernelInputData。カーネル内から値を返すvectorPtrと、この構造を持つものを指していることがわかります。( 1, 2, 3, 4, 5, ?, ?, ? )疑問符は通常 4293848814ですが、場合によっては0です。いずれにせよ、彼らがどうあるべきかではありません。

私は何が間違っているのですか?


編集:

ホスト側で配列の使用からcl_uint8に切り替えました。私は今持っています:

cl_uint8 dataVector = { 1, 2, 3, 4, 5, 6, 7, 8 };

そして、私はこのベクトルを次のようにカーネルに渡します。

clSetKernelArg(kernel, 0, sizeof(cl_uint8), &dataVector);

そして、カーネル関数のシグネチャは次のようになります。

kernel void kernelFunction(constant uint8 *vectorPtr)

ただし、このコードを実行すると、でCL_INVALID_ARG_SIZEエラーが発生しclSetKernelArg()ます。ARG_SIZEパラメータをに切り替えると、このエラーはsizeof(cl_uint8 *)なくなりますが、内でEXC_BAD_ACCESSエラーが発生します。__dynamic_castclSetKernelArg()

私のデバイスは:

Apple Macbook Pro(2009年半ば)
OSX 10.8 Mountain Lion
NVIDIA GeForce 9400M
OpenCL 1.0
CLH 1.0

4

2 に答える 2

8

サイズ8のcl_uintの配列を定義しています。cl_memの作成とカーネル引数の設定は正しいです。しかし、カーネルの引数は正しくありません。cl_uintではなくcl_uint8の配列を読み取ろうとします。

ベクトルデータ型を使用する場合は、次のように宣言する必要があります。サイズ1のcl_uint8 dataArr。または、サイズ8の配列を使用する場合:kernel void kernelFunction(constant uint *vectorPtr, uint size):

編集:

のカーネルパラメータcl_uint8 dataVectorはポインタではありません。したがって、正しいコードは次のとおりです。

cl_uint8 dataVector = { 1, 2, 3, 4, 5, 6, 7, 8 };
clSetKernelArg(kernel, 0, sizeof(cl_uint8), &dataVector);

kernel void kernelFunction(constant uint8 vectorPtr)
于 2012-10-29T08:58:25.780 に答える
1

実行可能な最小限の例

int2カーネルに渡されます。最初はの配列として作成されcl_intます。

#include <assert.h>
#include <stdlib.h>

#include <CL/cl.h>

int main(void) {
    const char *source =
        "__kernel void main(__global int2 *out) {\n"
        "      out[get_global_id(0)]++;\n"
        "}\n";
    cl_command_queue command_queue;
    cl_context context;
    cl_device_id device;
    cl_int input[] = {0, 1, 2, 3};
    const size_t global_work_size = sizeof(input) / sizeof(cl_int2);
    cl_kernel kernel;
    cl_mem buffer;
    cl_platform_id platform;
    cl_program program;

    clGetPlatformIDs(1, &platform, NULL);
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
    context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
    command_queue = clCreateCommandQueue(context, device, 0, NULL);
    buffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(input), &input, NULL);
    program = clCreateProgramWithSource(context, 1, &source, NULL, NULL);
    clBuildProgram(program, 1, &device, "", NULL, NULL);
    kernel = clCreateKernel(program, "main", NULL);
    clSetKernelArg(kernel, 0, sizeof(cl_mem), &buffer);
    clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL);
    clFlush(command_queue);
    clFinish(command_queue);
    clEnqueueReadBuffer(command_queue, buffer, CL_TRUE, 0, sizeof(input), &input, 0, NULL, NULL);

    assert(input[0] == 1);
    assert(input[1] == 2);
    assert(input[2] == 3);
    assert(input[3] == 4);
    return EXIT_SUCCESS;
}

Ubuntu 15.10 OpenCL 1.2NVIDIA352.53でテスト済み。

于 2016-03-30T21:44:30.987 に答える