- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
每次在命令队列上调用入队命令时,我都会得到返回值 CL_INVALID_COMMAND_QUEUE
。
样板文件(放置在 ctor 中)运行得很好,但是当我调用处理内核执行的函数时,它在第一个完成入队的位置发生故障。
我认为我的内核是完全正确的,因为任何 OpenCL C 编译器(AMD 的 vga 卡和 INTEL 的处理器)都没有抛出错误。空内核也出现同样的错误。
也许这只是一个小面包屑导致了这个问题,但我没有看到它。
下面向您展示了我的构造函数,它应该可以正常工作:
std::vector<cl_platform_id> this->OCLPlatformList;
std::vector<std::vector<cl_device_id>> this->OCLDevicesList;
std::vector<cl_context> this->OCLContext;
className::ctor()
{
this->FFT_SIZE_3 = this->configuration->getFFTSize(FFT_MULT::FFT_3);
cl_int err;
this->samplesInBuffer = new std::complex<float>[this->FFT_SIZE_3]();
// query OCL Platforms
cl_uint platformCount;
err = clGetPlatformIDs(0,NULL,&platformCount);
OCLCheckErr(err);
cl_platform_id* plBuffer = new cl_platform_id[platformCount];
err = clGetPlatformIDs(platformCount,plBuffer,NULL);
OCLCheckErr(err);
this->OCLPlatformList.resize((unsigned int)platformCount);
this->OCLDevicesList.resize((unsigned int)platformCount);
this->OCLContext.resize((unsigned int)platformCount);
for(cl_uint i = 0; i < platformCount; i++)
{
this->OCLPlatformList[i] = plBuffer[i];
}
delete[] plBuffer;
// query OCL Devices
cl_uint devCount;
for(unsigned int i = 0; i < this->OCLPlatformList.size() - 1; i++)
{
err = clGetDeviceIDs(this->OCLPlatformList[i],CL_DEVICE_TYPE_ALL,0,NULL,&devCount);
OCLCheckErr(err);
cl_device_id* devBuffer = new cl_device_id[devCount];
err = clGetDeviceIDs(this->OCLPlatformList[i],CL_DEVICE_TYPE_ALL,devCount,devBuffer,NULL);
OCLCheckErr(err);
this->OCLDevicesList[i].resize((unsigned int)devCount);
std::cout << std::endl << "Platform #" << i << ": " << OCLGetPlatformName(this->OCLPlatformList[i]) << std::endl;
for(cl_uint j = 0; j < devCount; j++)
{
this->OCLDevicesList[i][j] = devBuffer[j];
std::cout << "|-- Device #" << j << ": " << OCLGetDeviceName(this->OCLDevicesList[i][j]) << std::endl;
}
std::cout << std::endl;
delete[] devBuffer;
}
// create OCL Context
cl_context_properties* cprops = new cl_context_properties[3];
cprops[0] = ;
cprops[2] = 0;
for(unsigned int i = 0; i < this->OCLPlatformList.size() - 1; i++)
{
cl_device_id* devBuffer = new cl_device_id[this->OCLDevicesList[i].size()];
unsigned int j = 0;
for(std::vector<cl_device_id>::iterator it = this->OCLDevicesList[i].begin(); it != this->OCLDevicesList[i].end(); ++it)
devBuffer[j++] = *it;
cprops[1] = (cl_context_properties)this->OCLPlatformList[i];
this->OCLContext[i] = clCreateContext(cprops,(cl_uint)this->OCLDevicesList[i].size(),devBuffer,NULL,NULL,&err);
OCLCheckErr(err);
}
delete[] cprops;
// create OCL Command Queue
cl_queue_properties qprops[] =
{
CL_QUEUE_PROPERTIES,CL_QUEUE_ON_DEVICE_DEFAULT,0
};
this->OCLComQueue = clCreateCommandQueueWithProperties(this->OCLContext[0],this->OCLDevicesList[0][0],qprops,&err);
OCLCheckErr(err);
cl_int commSize;
err = clGetCommandQueueInfo(this->OCLComQueue,CL_QUEUE_SIZE,sizeof(cl_int),&commSize,NULL);
std::cout << this->OCLComQueue << " " << (long)commSize << std::endl;
OCLCheckErr(OCLCompileKernelFromSource(this->OCLProgram,"Kkernel.cl",this->OCLContext[0],this->OCLDevicesList[0][0],true));
this->kernel = clCreateKernel(this->OCLProgram,"Kkernel",&err);
OCLCheckErr(err);
// create OCL Buffer
//std::complex<float> this->BufferA[this->sizeA];
this->BufferACL = clCreateBuffer(this->OCLContext[0],(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR),
(this->sizeA * sizeof(std::complex<float>)),this->BufferA,&err);
OCLCheckErr(err);
//std::complex<float> this->BufferB[this->sizeB * this->k];
this->BufferBCL = clCreateBuffer(this->OCLContext[0],(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR),
(this->sizeB * this->k * sizeof(std::complex<float>)),BufferB,&err);
OCLCheckErr(err);
//std::complex<float> this->BufferB[this->l * this->k];
this->BufferCCL = clCreateBuffer(this->OCLContext[0],(CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR),
(this->l * this->k * sizeof(std::complex<float>)),this->BufferC,&err);
OCLCheckErr(err);
err = clSetKernelArg(this->kernel,0,sizeof(this->BufferACL),(void*)&this->BufferACL);
OCLCheckErr(err);
err = clSetKernelArg(this->kernel,1,sizeof(this->BufferBCL),(void*)&this->BufferBCL);
OCLCheckErr(err);
err = clSetKernelArg(this->kernel,2,sizeof(this->BufferCCL),(void*)&this->BufferCCL);
OCLCheckErr(err);
err = clSetKernelArg(this->kernel,3,sizeof(unsigned int),(void*)&this->k);
OCLCheckErr(err);
}
这是处理内核执行的函数的第一部分。如果我注释掉内存缓冲区的排队,它会在内核排队时失败:
void className::func1()
{
long c = this->k - 1;
for(std::list<std::complex<float>>::iterator it = this->sampleHistBuffer.begin(); it != this->sampleHistBuffer.end(); ++it)
{
cl_int err;
cl_event event;
clFinish(this->OCLComQueue);
OCLCheckErr(err);
err = clEnqueueWriteBuffer(this->OCLComQueue,this->BufferACL,CL_TRUE,0,(this->k * sizeof(std::complex<float>)),this->BufferA,0,NULL,&event);
OCLCheckErr(err);
cl_int state;
do
{
clGetEventInfo(event,CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof(state),&state,NULL);
if(state < 0)
throw 11;
}
while(state >= CL_COMPLETE);
size_t global_item_size = this->k * this->l;
size_t local_item_size = this->k;
err = clEnqueueNDRangeKernel(this->OCLComQueue,this->kernel,1,NULL,&global_item_size,&local_item_size,0,NULL,&event);
OCLCheckErr(err);
do
{
clGetEventInfo(event,CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof(state),&state,NULL);
if(state < 0)
throw 11;
}
while(state >= CL_COMPLETE);
/*...*/
}
最后但同样重要的是,这是内核的来源。它对 l 个工作组上的 k 个工作项执行乘法运算:
float2 cmult(float2 A, float2 B)
{
float2 ret;
ret.x = A.x * B.x;
ret.y = A.y * B.y;
return ret;
}
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__kernel void Kkernel(__global float2* BufferA, __global float2* BufferB, __global float2* BufferC, unsigned int k)
{
size_t sampleWrkGp = get_group_id(0);
size_t sampleWrkId = get_local_id(0);
BufferC[(sampleWrkId * k) + sampleWrkId] = cmult(BufferA[sampleWrkId],BufferB[(sampleWrkId * k) + sampleWrkId]);
}
如果有一些未描述的函数(如 OCLCheckErr()
),您可以确定它们是安全的,而不是问题所在。
最佳答案
看起来您正在创建一个设备上的命令队列 (CL_QUEUE_ON_DEVICE_DEFAULT),然后尝试使用它来对来自主机的命令进行排队。您只能从设备端使用设备端命令队列。使用常规命令队列 (clCreateCommandQueue) 进行主机端排队。
关于c++ - 调用任何入队命令时 OpenCL CL_INVALID_COMMAND_QUEUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33627647/
我正在研究在opencv中对某些图像应用meanshift的项目,经过四到五次尝试后,我收到此错误,我尝试了诸如关闭配置之类的操作,等等,但是它们都不起作用。任何帮助感激它。我的opencv 2.4.
我是 open CL 的新手,因此如果有人能提供帮助,我将不胜感激。我有一个小内核,它总是以 CL_INVALID_COMMAND_QUEUE 错误结束。我试过不同的硬件 gtx 765m 或 gtx
每次在命令队列上调用入队命令时,我都会得到返回值 CL_INVALID_COMMAND_QUEUE。 样板文件(放置在 ctor 中)运行得很好,但是当我调用处理内核执行的函数时,它在第一个完成入队的
我正在努力保存/加载二进制内核:如果我从源代码构建,程序运行良好。但是如果我编写内核并将其加载为二进制文件。我在调用 m_prog.getCommandQueues()[iDevice].enqueu
我在实现前馈多层感知器时遇到问题,使用 JOCL 在 Java 中的 OpenCL 中进行反向传播学习。下面是计算阶段的内核代码: #pragma OPENCL EXTENSION cl_kh
我是一名优秀的程序员,十分优秀!