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 から float 配列を削除すると、期待どおりに動作します。
過去に C/C++/Cli および CUDA C で作業していたので、エラーの性質を認識しています。Size
このエラーの解決策の中には、のパラメータを使用して構造体のサイズを手動で設定することを提案するものMarshalAs
がありますが、構造体内の型がさまざまであるため、これは不可能です。
生成された .cu ファイルを調べたところ、float 配列がfloat *
期待どおりに生成されています。
構造体内の配列をカーネルに渡す方法はありますか? そして、最良の第 2 の選択肢がない場合は? この問題は CUDA C には存在せず、CLR からマーシャリングしているためにのみ存在します。