Using VS 2012, .NET 4.5, 64bit and CUDAfy 1.12 and I have the following proof of concept
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();
}
}
}
When the program runs, I am getting the following error on the dev.Launch:
Type 'Test.ParentStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
If I remove the float array from the ChildStruct, it works as expected.
Having worked in C/C++/Cli and CUDA C in the past, I am aware of the nature of the error. Some solutions to this error suggest setting the struct size manually using Size
parameter of MarshalAs
, but this is not possible due to the variety of types within the struct.
I looked at the generated .cu file and it is generating the float array as a float *
which is what I expected.
Is there a way to pass an array within a struct to the Kernel? And if there isn't what is the best second alternative? This problem doesn't exist in CUDA C and it only exists because we are marshaling from CLR.