2013-05-02 76 views
2

使用VS 2012,.NET 4.5,64位和CUDAfy 1.12,我已經構思以下證明在CUDAfy傳遞一個結構中的數組

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 *

有沒有辦法將結構中的數組傳遞給內核?如果沒有什麼是最好的第二種選擇? CUDA C中不存在此問題,它只存在,因爲我們是從CLR編組。

+0

這是否也意味着列表將不可能與CUDAFY? – 2013-06-04 16:01:31

+1

首先,它需要是您要發送的數組,而不是列表。但是,我不認爲這是一個問題,除非你的結構有一個數組。 – Adam 2013-06-04 16:59:18

+0

好酷。該結構只包含日期時間,字符串十進制等我有一種感覺小數可能是一個問題,雖然我沒有看到它在「CUDA的例子」中提到。 + 1在你的評論和問題btw;) – 2013-06-04 17:10:45

回答

1

我花了很長時間閱讀CUDAfy的源代碼,看看是否有解決這個問題的方法。

CUDAfy試圖讓.NET開發人員變得過於簡單,並將它們從IntPtr和其他指針概念中屏蔽掉。然而,抽象層次使得如果不對該庫的工作方式進行重大重構,就很難想到這個問題的答案。

無法在結構中發送浮點數組是一種阻塞。我結束了對CUDA運行時的PInvoke,而不是使用CUDAfy。

+0

或者你可以發送psuedo ptr通過另一個數組,作爲C#和C++/ASM開發。我經常使用它,現在IMO c#集成需要這樣的解決方案;解耦內存管理。 – 2016-09-21 05:25:15

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]; 
} 

也沒有理由來存儲數組長度明確,因爲你可以使用設備代碼中的長度屬性。

+0

我看過這段代碼,但是它處理的是固定大小的數組,而且問題在於可變大小的數組。 – Adam 2013-05-08 23:32:19

+0

只需設置一個最大尺寸,然後將其餘值設爲空 – 2016-09-21 05:25:50

相關問題