gpt4 book ai didi

c++ - 简单 CUDA 测试总是失败并出现 "an illegal memory access was encountered"错误

转载 作者:可可西里 更新时间:2023-11-01 16:36:20 25 4
gpt4 key购买 nike

如果我运行这个程序,我会收到“在第 48 行的 matrixMulti.cu 中遇到非法内存访问”错误。我搜索并尝试了很多。所以我希望有人能帮助我。

Line 48 : HANDLE_ERROR ( cudaMemcpy(array, devarray, NNsizeof(int), cudaMemcpyDeviceToHost) );

该程序只是为了进入CUDA。我尝试实现矩阵乘法。

#include <iostream>
#include<cuda.h>
#include <stdio.h>

using namespace std;

#define HANDLE_ERROR( err ) ( HandleError( err, __FILE__, __LINE__ ) )
void printVec(int** a, int n);

static void HandleError( cudaError_t err, const char *file, int line )
{
if (err != cudaSuccess)
{
printf( "%s in %s at line %d\n", cudaGetErrorString( err ),
file, line );
exit( EXIT_FAILURE );
}
}

void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.\n", msg,
cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}
__global__ void MatrixMulti(int** a, int** b) {
b[0][0]=4;
}

int main() {
int N =10;
int** array, **devarray;
array = new int*[N];

for(int i = 0; i < N; i++) {
array[i] = new int[N];
}

HANDLE_ERROR ( cudaMalloc((void**)&devarray, N*N*sizeof(int) ) );
HANDLE_ERROR ( cudaMemcpy(devarray, array, N*N*sizeof(int), cudaMemcpyHostToDevice) );
MatrixMulti<<<1,1>>>(array,devarray);
HANDLE_ERROR ( cudaMemcpy(array, devarray, N*N*sizeof(int), cudaMemcpyDeviceToHost) );
HANDLE_ERROR ( cudaFree(devarray) );
printVec(array,N);

return 0;
}

void printVec(int** a , int n) {
for(int i =0 ; i < n; i++) {
for ( int j = 0; j <n; j++) {
cout<< a[i][j] <<" ";
}
cout<<" "<<endl;
}
}

最佳答案

一般来说,您分配和复制双下标 C 数组的方法是行不通的。 cudaMemcpy 需要平坦、连续分配、单指针、单下标数组。

由于这种混淆,传递给内核的指针 (int** a, int** b) 无法正确(安全地)解引用两次:

b[0][0]=4;

当您尝试在内核代码中执行上述操作时,您会获得非法内存访问,因为您没有在设备上正确分配指针到指针样式的分配。

如果您使用 cuda-memcheck 运行您的代码,您会在内核代码中得到另一个非法内存访问指示。

在这些情况下,通常的建议是将二维数组“扁平化”为一维,并使用适当的指针或索引算法来模拟二维访问。 有可能分配二维数组(即双下标、双指针),但它相当复杂(部分原因是需要“深拷贝”)。如果您想了解更多信息,只需在右上角搜索 CUDA 2D array

这是您的代码版本,其中对设备端数组进行了数组展平:

$ cat t60.cu
#include <iostream>
#include <cuda.h>
#include <stdio.h>

using namespace std;

#define HANDLE_ERROR( err ) ( HandleError( err, __FILE__, __LINE__ ) )
void printVec(int** a, int n);

static void HandleError( cudaError_t err, const char *file, int line )
{
if (err != cudaSuccess)
{
printf( "%s in %s at line %d\n", cudaGetErrorString( err ),
file, line );
exit( EXIT_FAILURE );
}
}

void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.\n", msg,
cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}

__global__ void MatrixMulti(int* b, unsigned n) {
for (int row = 0; row < n; row++)
for (int col=0; col < n; col++)
b[(row*n)+col]=col; //simulate 2D access in kernel code
}

int main() {
int N =10;
int** array, *devarray; // flatten device-side array
array = new int*[N];
array[0] = new int[N*N]; // host allocation needs to be contiguous
for (int i = 1; i < N; i++) array[i] = array[i-1]+N; //2D on top of contiguous allocation

HANDLE_ERROR ( cudaMalloc((void**)&devarray, N*N*sizeof(int) ) );
HANDLE_ERROR ( cudaMemcpy(devarray, array[0], N*N*sizeof(int), cudaMemcpyHostToDevice) );
MatrixMulti<<<1,1>>>(devarray, N);
HANDLE_ERROR ( cudaMemcpy(array[0], devarray, N*N*sizeof(int), cudaMemcpyDeviceToHost) );
HANDLE_ERROR ( cudaFree(devarray) );
printVec(array,N);

return 0;
}

void printVec(int** a , int n) {
for(int i =0 ; i < n; i++) {
for ( int j = 0; j <n; j++) {
cout<< a[i][j] <<" ";
}
cout<<" "<<endl;
}
}
$ nvcc -arch=sm_20 -o t60 t60.cu
$ ./t60
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
$

关于c++ - 简单 CUDA 测试总是失败并出现 "an illegal memory access was encountered"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25702573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com