好的,我使用的是CUDAfy.Net,我有以下3个结构:
[Cudafy]
public struct Collider
{
public int Index;
public int Type;
public Sphere Sphere;
public Plane Plane;
public Material Material;
}
[Cudafy]
public struct Material
{
public Color Color;
public Texture Texture;
public float Shininess;
}
[Cudafy]
public struct Texture
{
public int Width, Height;
public byte[ ] Data;
}现在,只要我将一个Collider对象数组发送到GPU,使用
CopyToDevice<GPU.Collider>( ColliderArray );我得到以下错误:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Object contains non-primitive or non-blittable data.有任何使用CUDAfy.Net或OpenCL (因为它基本上被编译成OpenCL )的经验的人,知道我如何实现这一点吗?整个问题在于Texture的字节数组,因为当我没有纹理结构时,一切都运行得很好,据我所知,数组是不可恢复的部分。我发现了几个关于同一问题的问题,他们使用固定大小的数组解决了这个问题。但是,我无法这样做,因为这些是纹理,它们的大小可能有很大的不同。
编辑:现在,我在CPU上执行以下操作:
public unsafe static GPU.Texture CreateGPUTexture( Cudafy.Host.GPGPU _GPU, System.Drawing.Bitmap Image )
{
GPU.Texture T = new GPU.Texture( );
T.Width = Image.Width;
T.Height = Image.Height;
byte[ ] Data = new byte[ Image.Width * Image.Height * 3 ];
for ( int X = 0; X < Image.Width; X++ )
for ( int Y = 0; Y < Image.Height; Y++ )
{
System.Drawing.Color C = Image.GetPixel( X, Y );
int ID = ( X + Y * Image.Width ) * 3;
Data[ ID ] = C.R;
Data[ ID + 1 ] = C.G;
Data[ ID + 2 ] = C.B;
}
byte[ ] _Data = _GPU.CopyToDevice<byte>( Data );
IntPtr Pointer = _GPU.GetDeviceMemory( _Data ).Pointer;
T.Data = ( byte* )Pointer.ToPointer( );
return T;
}然后我将这个纹理结构附加到对撞器上,并将它们发送到GPU。这一切都没有任何错误。但是,当我尝试在GPU上使用纹理时,如下所示:
[Cudafy]
public static Color GetTextureColor( int X, int Y, Texture Tex )
{
int ID = ( X + Y * Tex.Width ) * 3;
unsafe
{
byte R = Tex.Data[ ID ];
byte G = Tex.Data[ ID + 1 ];
byte B = Tex.Data[ ID + 2 ];
return CreateColor( ( float )R / 255f, ( float )G / 255f, ( float )B / 255f );
}
}我得到以下错误:
An unhandled exception of type 'Cloo.InvalidCommandQueueComputeException' occurred in Cudafy.NET.dll
Additional information: OpenCL error code detected: InvalidCommandQueue.顺便说一句,纹理结构看起来像这样:
[Cudafy]
public unsafe struct Texture
{
public int Width, Height;
public byte* Data;
}我又完全不知所措了..
发布于 2014-06-24 04:12:30
Cudafy还不支持数组。因此,既不能在结构中使用“公共byte[]数据”,也不能在内核本身中使用。您可以尝试使用更少的面向对象方法。我的意思是尝试从structre本身中移除数据数组,然后分别复制它们。例如copyToDevice(“纹理属性”),然后复制适当的数据数组copyToDevice(“纹理数据”)
编辑:好的,我找到了一个解决方案,但它不是很好的代码。
当你得到存储在GPU内存中的数据的指针时。将其转换为整数值pointer.ToInt64();并将该值简单地存储在结构对象中作为长值(而不是长指针)。然后,您可以使用GThread.InsertCode()方法将代码直接插入到内核中,而无需编译。不能在内核代码中直接使用指针,因为它们不是blittable数据类型。所以,停止说话这里是我的工作代码的示例
class Program
{
[Cudafy]
public struct TestStruct
{
public double value;
public long dataPointer; // your data pointer adress
}
[Cudafy]
public static void kernelTest(GThread thread, TestStruct[] structure, int[] intArray)
{
// Do something
GThread.InsertCode("int* pointer = (int*)structure[0].dataPointer;");
GThread.InsertCode("structure[0].value = pointer[1];"); // Here you can acces your data using pointer pointer[0], pointer[1] and so on
}
private unsafe static void Main(string[] args)
{
GPGPU gpuCuda = CudafyHost.GetDevice(eGPUType.Cuda, 0);
CudafyModule km = CudafyTranslator.Cudafy();
gpuCuda.LoadModule(km);
TestStruct[] host_array = new TestStruct[1];
host_array[0] = new TestStruct();
int[] host_intArray = new[] {1, 8, 3};
int[] dev_intArray = gpuCuda.CopyToDevice(host_intArray);
DevicePtrEx p = gpuCuda.GetDeviceMemory(dev_intArray);
IntPtr pointer = p.Pointer;
host_array[0].dataPointer = pointer.ToInt64();
TestStruct[] dev_array = gpuCuda.Allocate(host_array);
gpuCuda.CopyToDevice(host_array, dev_array);
gpuCuda.Launch().kernelTest(dev_array, dev_intArray);
gpuCuda.CopyFromDevice(dev_array, host_array);
Console.WriteLine(host_array[0].value);
Console.ReadKey();
}
}“魔术”是在InsertCode()中,您可以将长dataPointer值转换为整型指针地址...但是这种方法的缺点是你必须把代码的这些部分写成字符串。
或者,您可以将数据和结构分开,例如
[Cudafy]
public struct Texture
{
public int Width, Height;
}
[Cudafy]
public static void kernelTest(GThread thread, Texture[] TexStructure, byte[] Data)
{....}简单地复制
dev_Data = gpu.CopyToDevice(host_Data);
dev_Texture = gpu.CopyToDevice(host_Texture);
gpu.Launch().kernelTest(dev_Texture, dev_Data);编辑二:忘记我的代码:D
检查此https://cudafy.codeplex.com/discussions/538310,这是您的问题https://cudafy.codeplex.com/discussions/283527的解决方案
https://stackoverflow.com/questions/24355682
复制相似问题