这让我发疯了。我看了一遍,但我不确定我究竟究竟是什么导致了这个错误。
我正在调用一个DLL(我编写为一个单独的项目),它在我正在使用的一些数据上运行CUDA内核。虽然,我怀疑这个问题不是由CUDA造成的,因为代码已经过测试并至少运行一次,通常是64到100次,然后才会导致AccessViolationException。
问题是,我传递了三个公共静态数组:
public static float[] neuronInputs;
public static float[] connectionOutputs;
public static int[] calcOrder;
来自neuronInputs的数据被复制到GPU上,然后被操作,然后被复制回connectionOutputs(只读取calcOrder,但不写入)。我使用connectionOutputs数组执行一系列操作。然后我写下了neuronInputs数组,并将其发送回GPU。重复直到失败。它总是失败。
我正在调用此函数:
[DllImport("CUDANeural.dll")]
static extern void GenerateSubstrateConnections(
[In, Out] [MarshalAs(UnmanagedType.LPArray)] float[] neuronInputs,
[In, Out] [MarshalAs(UnmanagedType.LPArray)] int[] calcOrder,
[In, Out] [MarshalAs(UnmanagedType.LPArray)] float[] outWeights
);
我只为三个数组分配一次内存,并为每个数组分配一个大块。我已经在托管端测试了它,并且我无法在CUDA代码中的数组之外进行索引。
我想我的问题是,导致此AccessViolationException的原因是什么?假设它不是CUDA代码。
编辑: 这是来自非管理方的电话
extern "C" __declspec(dllexport) void GenerateSubstrateConnections(
float* neuronInputs, int* calcOrder, float* outWeights);
似乎我对CUDA编程方面可能有所错。我在对GenerateSubstrateConnections的调用结束时添加了一个cudaExitThread()调用,这似乎纠正了这个问题。但是,为了澄清,我称之为不同的功能:
[DllImport("CUDANeural.dll")]
static extern void DebugSubstrateConnections(
[In, Out] IntPtr neuronInputs,
[In, Out] IntPtr calcOrder,
[In, Out] IntPtr outWeights
);
在我在托管代码中调用GenerateSubstrateConnections之前,我确定了GCHandles
SubstrateDescription.inputHandle = GCHandle.Alloc(SubstrateDescription.neuronInputs, GCHandleType.Pinned);
SubstrateDescription.connectionHandle = GCHandle.Alloc(SubstrateDescription.outputConnections, GCHandleType.Pinned);
calcHandle = GCHandle.Alloc(calcOrder, GCHandleType.Pinned);
然后致电
GenerateSubstrateConnections(
SubstrateDescription.inputHandle.AddrOfPinnedObject(),
calcHandle.AddrOfPinnedObject(),
SubstrateDescription.connectionHandle.AddrOfPinnedObject());
我不完全确定这是否有必要,但我知道它有效(目前)。感谢您的所有评论,他们帮助我解决了这个问题。
答案 0 :(得分:1)
可能是线程安全问题。由于您使用的是静态内存,因此您应该锁定对象,或者使用其他一些同步选项,除非您完全确定它是单线程的。
答案 1 :(得分:1)
我不确定你是否可以对CUDA函数进行简单的pInvoke,因为它们没有在主处理器上运行。直接使用本机CUDA API的最佳选择可能是使用C ++ / CLI。 nVidia刚刚发布了支持包。 其他更简单的选项包括使用OPENCL,它具有名为OpenTK的.Net库,可为大多数用途提供托管包装。