1

I am using CUDAfy .NET and want to pass a struct array within a struct to the device.

I have declared them in c# as shown below:

[Cudafy(eCudafyType.Struct)]
[StructLayout(LayoutKind.Sequential)]
public struct A
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType= UnmanagedType.Struct, SizeConst = 3)]
    public B[] ba;
}

[Cudafy(eCudafyType.Struct)]
[StructLayout(LayoutKind.Sequential)]
public struct B
{
    public byte id;
 }

This results in the following source code for the GPU:

struct B
{
        unsigned char id;
};


struct A
{
        B ba [3]; 
        int baLen0;
 };

And I get this compilation error from an attempt to convert it to OpenCL code:

Compilation error: <kernel>:20:2: error: must use 'struct' tag to refer to type 'B'
    B ba [3]; int baLen0;
    ^
    struct

I realize this could be an issue between the marshalling and how CUDAfy .NET handles structures, but is there any way I could possibly fix this?

Thanks in advance

pcaston2
  • 421
  • 1
  • 6
  • 17
  • And if you put `struct` before `B ba [3];` and attempt recompilation? If I remember from C/C++ correctly, non-`typedef`-ed structs must include the `struct` keyword when refering to that value-type. – Maximilian Gerhardt Apr 21 '16 at 15:57
  • I believe this would work, however the C/C++ code is an intermediate step that is generated. If I could accomplish it with marshalling somehow, or make a change such that the struct is not nessesary, I believe the issue would be resolved. – pcaston2 Apr 21 '16 at 16:47

1 Answers1

1

I managed to alter the CUDAfy .NET library in the CudafyTranslator. After the structs were in a memory stream I added:

        StreamReader sr = new StreamReader(structs);
        String sStructs = sr.ReadToEnd();
        String sNewStructs;
        foreach(string structName in cm.Types.Values.Select(t => t.Name))
        {
            while (true)
            {
                string regex = @"^(?<start>\s+)" + structName + @"(?<end>\s+\S+( \[\d+\])?;)";
                sNewStructs = Regex.Replace(sStructs, regex, @"${start}struct " + structName + "${end}", RegexOptions.Multiline);
                if (sNewStructs.Length == sStructs.Length)
                {
                    break;
                } else
                {
                    sStructs = sNewStructs;
                }
            }
        }
        structs = new MemoryStream();
        StreamWriter sw = new StreamWriter(structs);
        sw.WriteLine(sStructs);
        sw.Flush();

It's a bit sloppy but it works, I then rebuilt CUDAfy .NET and ilmerged it and replaced my dll

pcaston2
  • 421
  • 1
  • 6
  • 17