Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyCUDA LogicError:cuModuleLoadDataEx失败:遇到非法内存访问_Python_Cuda_Pycuda - Fatal编程技术网

Python PyCUDA LogicError:cuModuleLoadDataEx失败:遇到非法内存访问

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

我试图将双音排序与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

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