私はopenCLを初めて使用し、非常に単純なカーネルから始めようとしています。現在、正しいデータが設定されていることを確認できるように、データをカーネルに転送して戻すことを試みています。しかし、私は非常に奇妙な振る舞いをしています。これが私のホストコードです:
string PROGRAM_FILE = "C:\\Projects\\AnimatLabSDK\\OpenNeuronCL\\Libraries\\OpenNeuronCL\\Kernels\\FastSpikingNeuron.cl";
string KERNEL_FUNC = "FastSpikingNeuron";
std::vector<cl::Platform> platforms;
std::vector<cl::Device> devices;
int i;
// Data
cl::NDRange ndGlobal(DATA_SIZE);
cl::NDRange ndLocal(LOCAL_SIZE);
cl_float aryVmIn[DATA_SIZE], aryVmOut[DATA_SIZE];
cl_float aryVahp[DATA_SIZE], aryTestOut[DATA_SIZE];
try {
// Initialize data
for(i=0; i<DATA_SIZE; i++) {
aryVmIn[i] = i*0.1f; //0.0f;
aryVahp[i] = i*0.1f; //0.0f;
}
// Place the GPU devices of the first platform into a context
cl::Platform::get(&platforms);
platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &devices);
cl::Context context(devices);
// Create kernel
std::ifstream programFile(PROGRAM_FILE);
std::string programString(std::istreambuf_iterator<char>(programFile),
(std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(programString.c_str(),
programString.length()+1));
cl::Program program(context, source);
//std::cout << "Program kernel: " << std::endl << programString << std::endl;
try
{
program.build(devices);
}
catch(cl::Error e)
{
std::cout << e.what() << ": Error code " << e.err() << std::endl;
string buildlog;
program.getBuildInfo( devices[0], (cl_program_build_info)CL_PROGRAM_BUILD_LOG, &buildlog );
std::cout << "Error: " << buildlog << std::endl;
throw e;
}
cl::Kernel kernel(program, KERNEL_FUNC.c_str());
// Create buffers
cl::Buffer bufferVmIn(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(aryVmIn), aryVmIn);
cl::Buffer bufferVmOut(context, CL_MEM_WRITE_ONLY, sizeof(aryVmOut), NULL);
cl::Buffer bufferVahp(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(aryVahp), aryVahp);
cl::Buffer bufferTestOut(context, CL_MEM_WRITE_ONLY, sizeof(aryTestOut), NULL);
// Set kernel arguments
kernel.setArg(0, bufferVmIn);
kernel.setArg(1, bufferVmOut);
kernel.setArg(2, bufferVahp);
kernel.setArg(3, bufferTestOut);
// Create queue and enqueue kernel-execution command
cl::CommandQueue queue(context, devices[0]);
queue.enqueueWriteBuffer(bufferVmIn, CL_TRUE, 0, sizeof(aryVmIn), aryVmIn, NULL, NULL);
queue.enqueueWriteBuffer(bufferVahp, CL_TRUE, 0, sizeof(aryVahp), aryVahp, NULL, NULL);
queue.enqueueNDRangeKernel(kernel, NULL, ndGlobal, ndLocal);
queue.enqueueReadBuffer(bufferVmOut, CL_TRUE, 0, sizeof(aryVmOut), aryVmOut, NULL, NULL);
queue.enqueueReadBuffer(bufferTestOut, CL_TRUE, 0, sizeof(aryTestOut), aryTestOut, NULL, NULL);
// Display updated buffer
for(i=0; i<10; i++)
{
printf("%6.5f, %6.5f", aryVmOut[i], aryTestOut[i]);
printf("\n");
}
}
catch(cl::Error e)
{
std::cout << e.what() << ": Error code " << e.err() << std::endl;
}
そして、これが私のカーネルです:
__kernel void FastSpikingNeuron(__global float *aryVmIn, __global float *aryVmOut, __global float *aryVahp, __global float *aryTestOut)
{
int gid = get_global_id(0);
local float fltVahp;
fltVahp = aryVahp[gid];
aryVmOut[gid] = fltVahp;
aryTestOut[gid] = fltVahp;
}
私は単にいくつかのデータを設定し、次にVmoutとTestOutを読み取って、それらの内容のいくつかを表示しようとしています。このアプリケーションを実行すると、次の出力が得られます。
0.00000, 0.90000
0.10000, 0.90000
0.20000, 0.90000
0.30000, 0.90000
0.40000, 0.90000
0.50000, 0.90000
0.60000, 0.90000
0.70000, 0.90000
0.80000, 0.90000
0.90000, 0.90000
これは今のところ私には意味がありません。カーネルでは、VmOutとTestOutの両方をまったく同じ変数に設定していますが、それをホストに読み戻すと、異なる結果が得られます。私はここで何か間違ったことをしていますが、それが何であるかをまだ理解できていません。openclの経験が豊富な人からの助けをいただければ幸いです。
ありがとうDavid