{"id":4515,"date":"2014-03-30T13:08:35","date_gmt":"2014-03-30T13:08:35","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/passing-an-array-within-a-structure-in-cudafy-collection-of-common-programming-errors\/"},"modified":"2014-03-30T13:08:35","modified_gmt":"2014-03-30T13:08:35","slug":"passing-an-array-within-a-structure-in-cudafy-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/passing-an-array-within-a-structure-in-cudafy-collection-of-common-programming-errors\/","title":{"rendered":"Passing an array within a structure in CUDAfy-Collection of common programming errors"},"content":{"rendered":"<p>Using VS 2012, .NET 4.5, 64bit and CUDAfy 1.12 and I have the following proof of concept<\/p>\n<pre><code>using System;\nusing System.Runtime.InteropServices;\nusing Cudafy;\nusing Cudafy.Host;\nusing Cudafy.Translator;\n\nnamespace Test\n{\n[Cudafy(eCudafyType.Struct)]\n[StructLayout(LayoutKind.Sequential)]\npublic struct ChildStruct\n{\n    [MarshalAs(UnmanagedType.LPArray)]\n    public float[] FArray;\n    public long FArrayLength;\n}\n\n[Cudafy(eCudafyType.Struct)]\n[StructLayout(LayoutKind.Sequential)]\npublic struct ParentStruct\n{\n    public ChildStruct Child;\n}\n\npublic class Program\n{\n    [Cudafy]\n    public static void KernelFunction(GThread gThread, ParentStruct parent)\n    {\n        long length = parent.Child.FArrayLength;\n    }\n\n    public static void Main(string[] args)\n    {\n        var module = CudafyTranslator.Cudafy(\n          ePlatform.x64, eArchitecture.sm_35,\n          new[] {typeof(ChildStruct), typeof(ParentStruct), typeof(Program)});\n        var dev = CudafyHost.GetDevice();\n        dev.LoadModule(module);\n\n        float[] hostFloat = new float[10];\n        for (int i = 0; i &lt; hostFloat.Length; i++) { hostFloat[i] = i; }\n\n        ParentStruct parent = new ParentStruct\n        {\n            Child = new ChildStruct\n            {\n                FArray = dev.Allocate(hostFloat),\n                FArrayLength = hostFloat.Length\n            }\n        };\n\n        dev.Launch(1, 1, KernelFunction, parent);\n\n        Console.ReadLine();\n    }\n}\n}\n<\/code><\/pre>\n<p>When the program runs, I am getting the following error on the dev.Launch:<\/p>\n<p><code>Type 'Test.ParentStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.<\/code><\/p>\n<p>If I remove the float array from the ChildStruct, it works as expected.<\/p>\n<p>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 <code>Size<\/code> parameter of <code>MarshalAs<\/code>, but this is not possible due to the variety of types within the struct.<\/p>\n<p>I looked at the generated .cu file and it is generating the float array as a <code>float *<\/code> which is what I expected.<\/p>\n<p><strong>Is there a way to pass an array within a struct to the Kernel? And if there isn&#8217;t what is the best second alternative?<\/strong> This problem doesn&#8217;t exist in CUDA C and it only exists because we are marshaling from CLR.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4515","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=4515"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4515\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=4515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=4515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=4515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}