Python PyCUDA LogicError:cuModuleLoadDataEx失败:遇到非法内存访问
我试图将双音排序与pycuda并行。为此,我使用SourceModule和并行双音排序的C代码。对于内存拷贝管理,我使用pycuda.driver中的InOut来简化一些内存传输Python PyCUDA LogicError:cuModuleLoadDataEx失败:遇到非法内存访问,python,cuda,pycuda,Python,Cuda,Pycuda,我试图将双音排序与pycuda并行。为此,我使用SourceModule和并行双音排序的C代码。对于内存拷贝管理,我使用pycuda.driver中的InOut来简化一些内存传输 import pycuda.autoinit import pycuda.driver as drv from pycuda.compiler import SourceModule from pycuda import gpuarray import numpy as np from time import time
import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule
from pycuda import gpuarray
import numpy as np
from time import time
ker = SourceModule(
"""
__device__ void swap(int & a, int & b){
int tmp = a;
a = b;
b = tmp;
}
__global__ void bitonicSort(int * values, int N){
extern __shared__ int shared[];
int tid = threadIdx.x + blockDim.x * blockIdx.x;
// Copy input to shared mem.
shared[tid] = values[tid];
__syncthreads();
// Parallel bitonic sort.
for (int k = 2; k <= N; k *= 2){
// Bitonic merge:
for (int j = k / 2; j>0; j /= 2){
int ixj = tid ^ j;
if (ixj > tid){
if ((tid & k) == 0){
//Sort ascending
if (shared[tid] > shared[ixj]){
swap(shared[tid], shared[ixj]);
}
}
else{
//Sort descending
if (shared[tid] < shared[ixj]){
swap(shared[tid], shared[ixj]);
}
}
}
__syncthreads();
}
}
values[tid] = shared[tid];
}
"""
)
N = 8 #lenght of A
A = np.int32(np.random.randint(1, 20, N)) #random numbers in A
BLOCK_SIZE = 256
NUM_BLOCKS = (N + BLOCK_SIZE-1)//BLOCK_SIZE
bitonicSort = ker.get_function("bitonicSort")
t1 = time()
bitonicSort(drv.InOut(A), np.int32(N), block=(BLOCK_SIZE,1,1), grid=(NUM_BLOCKS,1), shared=4*N)
t2 = time()
print("Execution Time {0}".format(t2 - t1))
print(A)
有人知道是什么导致了这个错误吗?您的设备代码没有正确地说明阵列的大小 在单个块中启动256个线程。这意味着您将有256个线程,编号为0..255的
tid
试图执行每一行代码。例如,在这种情况下:
shared[tid] = values[tid];
例如,您将有一个线程尝试执行shared[255]=value[255]代码>
您的共享
或值
数组都没有那么大。这就是非法内存访问错误的原因
对于这类琐碎问题,最简单的解决方案是使数组大小与块大小匹配
BLOCK_SIZE = N
根据我的测试,该更改将清除所有错误并生成正确排序的数组
它不适用于大于1024的N
或多块使用,但无论如何,您的代码必须修改为多块排序
如果在进行更改后仍有问题,我建议重新启动python会话或colab会话。虽然您的观察是正确的,但我认为这实际上不是运行时代码问题,而是运行时构建问题。通常情况下,编译器基础结构内部的这种爆炸意味着PyCUDA和宿主ToolKit之间的工具链/不兼容可能是错误的。我无法假设该错误会在模块加载时发生的原因,因此我猜测它是上次运行时遗留下来的,并且由于python的一些交互使用而没有被清除。这就是为什么我在回答中作了最后的评论。我不知道为什么这个错误会发生在模块加载时,对于一个新的运行(这似乎是不可能的)。通过我建议的更改,我至少可以断言它对我来说运行正确,因此如果问题仍然存在,我不相信代码中存在问题。这解决了我的问题,非常感谢。我必须修改代码以使用多块排序,有什么提示吗?要在GPU上对数字进行排序,我将使用库实现。如果您想自己编写代码(不推荐),那么有一种方法可以执行多块双音排序。
BLOCK_SIZE = N