C# 如果我使用其他GPU,为什么我的OpenCL功能不能工作?
我用我的GPU控制大阵列,在我的第一台PC(有AMD RX 570)上一切正常,但在第二台PC(Nvidia 920m)上,我的功能不起作用,我的应用程序崩溃,因为复制的阵列被0填充 这是我的函数(我添加了prinf来检查我的程序是否实际在使用它):C# 如果我使用其他GPU,为什么我的OpenCL功能不能工作?,c#,arrays,opencl,C#,Arrays,Opencl,我用我的GPU控制大阵列,在我的第一台PC(有AMD RX 570)上一切正常,但在第二台PC(Nvidia 920m)上,我的功能不起作用,我的应用程序崩溃,因为复制的阵列被0填充 这是我的函数(我添加了prinf来检查我的程序是否实际在使用它): kernelvoidarraycopy(全局uchar*bufferIn,int-inOffset, 全局uchar*缓冲输出,整数输出偏移) { int index=get_global_id(0); bufferOut[index+outOff
kernelvoidarraycopy(全局uchar*bufferIn,int-inOffset,
全局uchar*缓冲输出,整数输出偏移)
{
int index=get_global_id(0);
bufferOut[index+outOffset]=bufferIn[index+inooffset];
printf(“它起作用了!”);
}
我不知道为什么Cloo
没有给我一个异常、警告或其他任何东西
在调试应用程序时,我发现了一些有关图形卡的数据:
sockets
,所以这些数组将是字节数组(byte[]
),即uchar*
我使用Nodaways重建这些图像,由于阵列的大小,重建速度非常慢。因此,我使用Cloo
编写了一个函数,它接受5个参数(比如System.Array.Copy
):
- bufferIn(源阵列)
- inOffset(开始读取值的源索引)
- 缓冲输出(目标阵列)
- 超出偏移量(开始设置值的目的地索引)
- 长度(要复制的元素数)
public void GPUCopy(字节[]bufferIn,int-inOffset,字节[]bufferOut,int-outOffset,int-lenght)
{
ComputeBuffer originBuffer,destBuffer;
originBuffer=新的ComputeBuffer(上下文,
ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer,bufferIn);
destBuffer=newcomputebuffer(上下文,
ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer,bufferOut);
SetMemoryArgument(0,originBuffer);
SetValueArgument(1,inOffset);
SetMemoryArgument(2,destBuffer);
SetValueArgument(3,outOffset);
Execute(kernel,new long[]{0},new long[]{lenght},null,new ComputeEventList());
queue.Finish();
}
正如我之前所说,这与我的RX 570配合得很好,并且在我的920m上没有错误
完整类源代码如下:
类GPU
{
私有ComputeCommandQueue队列;
私有计算上下文;
私有计算机内核;
私有字符串数组复制
{
得到
{
返回@”
内核void ArrayCopy(全局uchar*bufferIn、int-inOffset、全局uchar*bufferOut、int-outOffset)
{
int index=get_global_id(0);
bufferOut[index+outOffset]=bufferIn[index+inooffset];
}";
}
}
公共GPU()
{
context=new ComputeContext(ComputeDeviceTypes.Gpu,new ComputeContextPropertyList(ComputePlatform.Platforms[0]),null,IntPtr.Zero);
队列=新的ComputeCommandQueue(上下文,context.Devices[0],ComputeCommandQueueFlags.None);
var程序=新的计算程序(上下文,ArrayCopy);
Build(null,null,null,IntPtr.Zero);
kernel=program.CreateKernel(“ArrayCopy”);
}
public void GPUCopy(字节[]bufferIn,int-inOffset,字节[]bufferOut,int-outOffset,int-lenght)
{
ComputeBuffer originBuffer,destBuffer;
originBuffer=新的ComputeBuffer(上下文,
ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer,bufferIn);
destBuffer=newcomputebuffer(上下文,
ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer,bufferOut);
SetMemoryArgument(0,originBuffer);
SetValueArgument(1,inOffset);
SetMemoryArgument(2,destBuffer);
SetValueArgument(3,outOffset);
Execute(kernel,new long[]{0},new long[]{lenght},null,new ComputeEventList());
queue.Finish();
}
}
您在问题中提供的信息非常少,但我能想到一些您需要检查或尝试的东西,而评论对此有些尴尬,因此这里有一个“答案”:
- 您的上下文符合哪个版本的OpenCL?在OpenCL1.0中,字节寻址不是内置的,一次只能复制一个字节(
)。因此,如果您的上下文是OpenCL1.0上下文,请检查您的设备是否支持,并在内核中启用它。(在OpenCL1.1及更新版本中,您不需要这样做。)uchar
- 如果以上不是问题的原因,我希望主机端会返回一些错误。你确定你检查的足够了吗?我不熟悉cloo包装器,似乎没有任何文档(?),但在普通OpenCL中,几乎每个主机函数都会返回某种类型的结果代码,如果不检查并处理它,通常会导致您看到的那种行为
- 如果您的内核真的像您所发布的那样,这不仅仅是一个简化的示例:对于复制缓冲区子范围,您可能应该使用,它使用设备的DMA引擎(如果可用),而不是自定义内核。如果这在任何OpenCL实现中都比较慢,并且在某些情况下会更快,我会非常惊讶
printf
-请删除它并重新测试。@Doq或者我的第一次尝试没有printf,没有任何更改。然后需要更多信息