2

使用 VS 2012、.NET 4.5、64 位和 CUDAfy 1.12,我有以下概念证明

using System;
using System.Runtime.InteropServices;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;

namespace Test
{
[Cudafy(eCudafyType.Struct)]
[StructLayout(LayoutKind.Sequential)]
public struct ChildStruct
{
    [MarshalAs(UnmanagedType.LPArray)]
    public float[] FArray;
    public long FArrayLength;
}

[Cudafy(eCudafyType.Struct)]
[StructLayout(LayoutKind.Sequential)]
public struct ParentStruct
{
    public ChildStruct Child;
}

public class Program
{
    [Cudafy]
    public static void KernelFunction(GThread gThread, ParentStruct parent)
    {
        long length = parent.Child.FArrayLength;
    }

    public static void Main(string[] args)
    {
        var module = CudafyTranslator.Cudafy(
          ePlatform.x64, eArchitecture.sm_35,
          new[] {typeof(ChildStruct), typeof(ParentStruct), typeof(Program)});
        var dev = CudafyHost.GetDevice();
        dev.LoadModule(module);

        float[] hostFloat = new float[10];
        for (int i = 0; i < hostFloat.Length; i++) { hostFloat[i] = i; }

        ParentStruct parent = new ParentStruct
        {
            Child = new ChildStruct
            {
                FArray = dev.Allocate(hostFloat),
                FArrayLength = hostFloat.Length
            }
        };

        dev.Launch(1, 1, KernelFunction, parent);

        Console.ReadLine();
    }
}
}

当程序运行时,我在 dev.Launch 上收到以下错误:

Type 'Test.ParentStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

如果我从 ChildStruct 中删除浮点数组,它会按预期工作。

过去曾在 C/C++/Cli 和 CUDA C 中工作过,我知道错误的性质。此错误的一些解决方案建议使用Size参数手动设置结构大小MarshalAs,但由于结构内的类型多种多样,这是不可能的。

我查看了生成的 .cu 文件,它正在生成浮点数组,float *这是我所期望的。

有没有办法将结构中的数组传递给内核?如果没有最好的第二种选择是什么?这个问题在 CUDA C 中不存在,它只是因为我们从 CLR 编组而存在。

4

2 回答 2

1

这是 .NET 的限制,而不是 CUDAfy。数据必须是 blittable 并且非固定大小的数组不是。这是有效的,并且基于 codeplex 上的 CUDAfy 单元测试:

[Cudafy]
[StructLayout(LayoutKind.Sequential, Size=64, CharSet = CharSet.Unicode)]
public unsafe struct PrimitiveStruct
{
    public fixed sbyte Message[32];
    public fixed char MessageChars[16];
}

也没有理由显式存储数组长度,因为您可以在设备代码中使用 Length 属性。

于 2013-05-08T22:01:53.207 回答
1

我花了很多时间阅读 CUDAfy 的源代码,看看是否有解决这个问题的方法。

CUDAfy 试图让 .NET 开发人员的事情变得过于简单,并使他们远离 .NETIntPtr和其他指针概念。但是,如果不对这个库的工作方式进行重大重构,那么抽象级别就很难想出解决这个问题的办法。

无法在结构中发送浮点数组是一个显示停止器。我最终对 CUDA Runtime 进行了 PInvoke,而不是使用 CUDAfy。

于 2013-05-04T21:44:16.727 回答