Это сводит меня с ума. Я просмотрел все, но не уверен, что точно понимаю, что является причиной этой ошибки.
Я обращаюсь к DLL (которую я кодировал как отдельный проект), которая запускает ядро CUDA для некоторых данных, которые я использую. Хотя я подозреваю, что проблема не в CUDA, так как код был протестирован и работает по крайней мере один раз, и обычно 64-100 раз, прежде чем вызвать AccessViolationException.
Проблема в том, что я передаю три открытых статических массива:
public static float[] neuronInputs;
public static float[] connectionOutputs;
public static int[] calcOrder;
Данные из neuronInputs копируются в GPU, обрабатываются, а затем копируются обратно в connectionOutputs (calcOrder только читается, но не записывается). Я выполняю кучу операций, используя массив connectionOutputs. Затем я переписываю массив neuronInputs и отправляю его обратно в графический процессор. Повторять пока не получится. И это всегда терпит неудачу.
Я вызываю эту функцию:
[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.
EDIT:
Вот звонок с неуправляемой стороны
<code>extern "C" __declspec(dllexport) void GenerateSubstrateConnections(<br>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());
Я не совсем уверен, если это необходимо, но я знаю, что это работает (в настоящее время). Спасибо за все комментарии, они помогли мне выжать проблему.