c++ - 我使用统一内存运行内核函数后无法访问它

标签 c++ parallel-processing cuda gpu

所以我在我的代码中为2个函数调用cudaMallocManaged,并且它对于第一个函数(backwardMask())工作正常,在我调用它之后我可以轻松地从主机访问我的数据,但我的问题是内核函数seriesLength() -因为我在我的索引掩码上执行 cudaMallocManaged 然后(在调用 seriesLength() 之前)我可以轻松地访问/修改主机上的这个索引掩码,在我调用 seriesLength() 之后它正在修改我的索引掩码并且访问它也没有问题,但是之后此函数返回我无法读取主机上的索引掩码并且出现异常(状态代码0xC0000022)。

这是一个非常奇怪的错误,因为我的做法与第一个函数(backwardMask())类似,它工作正常。

任何想法/解释都将受到高度赞赏。

这里是seriesLengths核心函数代码:

__global__ void seriesLengths(int* scannedbw,int* indexmask,int* numOfSeries,int n){
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
 for (int i = index; i < n;i+=stride)
 {
    if (i == (n - 1))
    {
        *numOfSeries = scannedbw[i];
        indexmask[scannedbw[i]] = n;
    }
    if (i == 0)
    {
        indexmask[0] = 0;
    }
    else if (scannedbw[i] != scannedbw[i - 1])
    {
        indexmask[scannedbw[i] - 1] = i;
    }
 }
}

内核函数b​​ackwardMask代码:

__global__ void backwardMask(const char *in, int* bwMask,int n)
{
    int index = blockIdx.x * blockDim.x + threadIdx.x;
    int stride = blockDim.x * gridDim.x;
    for (int i = index; i < n;i+=stride)
    {
        if (i == 0)
            bwMask[i] = 1;
        else 
        {
            bwMask[i] = (in[i] != in[i - 1]);
        }
    }
}

主要功能:

int main()
{
    int N=1024;
    srand(time(0));
    char* t;
    int* bwmask;
    cudaMallocManaged(&t, N*sizeof(char));
    cudaMallocManaged(&bwmask, N*sizeof(int));
    for (int i = 0; i < N; i++)
    {
        if(i<300)
        t[i] = 'a' + rand() % 2;
        else
            t[i] = 'a' + rand() % 20;

    }

    for (int j = 0; j < 60; j++)
        std::cout << t[j];
    std::cout << std::endl;
    int blockSize = 256;
    int numBlocks = (N + blockSize - 1) / blockSize;
    backwardMask<<<numBlocks, blockSize >>>(t,bwmask , N);
    cudaDeviceSynchronize();
    for (int j = 0; j < 60; j++)
        std::cout << bwmask[j];
    std::cout << std::endl;
    //now inclusive prefix sum for bwmask
    int* scannedbwmask;
    cudaMallocManaged(&scannedbwmask, N*sizeof(int));

    thrust::inclusive_scan(bwmask, bwmask + N, scannedbwmask);
    cudaDeviceSynchronize();

    int numOfSeries;
    //seriesLengths shows us lengths of each series by i-(i-1) and starting index of each series
    int* indexmask;
    cudaMallocManaged(&indexmask, (N+1)*sizeof(int));
    seriesLengths<<<numBlocks, blockSize>>>(scannedbwmask, indexmask, &numOfSeries, N);
    cudaDeviceSynchronize();

// accessing indexmask here gives us exception
    std::cout << indexmask[3];
    /*for (int j = 0; j < 60; j++)
        std::cout << indexmask[j];
    std::cout << std::endl;*/
    std::cout << "numseries " << numOfSeries;


    getch();
    return 0;
}

最佳答案

将 numOfSeries 更改为指向 int 的指针

int* numOfSeries;

然后为它分配内存:

cudaMallocManaged(&numOfSeries, sizeof(int));

然后像这样传递它:

seriesLengths<<<numBlocks, blockSize>>>(scannedbwmask, indexmask, numOfSeries, N);

关于c++ - 我使用统一内存运行内核函数后无法访问它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43679680/

相关文章:

C++ 如何将任何类(自定义)对象转换为 vector <unsigned char>

bash - 并行 for 循环

windows - CUDA、Win7、Qt 创建者 - LNK1104 : cannot open file '<cuda file>.obj'

c++ - 与 FFT 的卷积,这是如何工作的?

c++ - 重载 std::string 构造函数

c++ - 没有规则使目标 *.so

c++ - if (!x) 和 if (x == nullptr) 之间有什么区别吗?

c - MPI_Scatter 段错误(信号 11)

c++ - 等待条件变量后线程未并行运行

algorithm - 区域距离