Cuda内存错误(分配和复制成功)
我目前学习CUDA是为了实现高性能计算。我有一个实现Jacobi迭代的项目。我的程序中有一个内存错误,我很难找到它 我的Jacobi内核正确地运行了一次迭代,现在我正在计算旧矩阵和新矩阵之间的最大差值。如果我注释掉下一行代码:Cuda内存错误(分配和复制成功),cuda,gpu,Cuda,Gpu,我目前学习CUDA是为了实现高性能计算。我有一个实现Jacobi迭代的项目。我的程序中有一个内存错误,我很难找到它 我的Jacobi内核正确地运行了一次迭代,现在我正在计算旧矩阵和新矩阵之间的最大差值。如果我注释掉下一行代码: //diff[idx] = BJacobi[idx] - AJacobi[idx]; 它起作用了。但是,包含这行代码会导致BJacbi的数据被AJacobi的部分数据覆盖(或者至少我认为这是AJacobi的数据,几乎是相同的模式)。对我来说,这似乎是一个分配问题,但我不
//diff[idx] = BJacobi[idx] - AJacobi[idx];
它起作用了。但是,包含这行代码会导致BJacbi的数据被AJacobi的部分数据覆盖(或者至少我认为这是AJacobi的数据,几乎是相同的模式)。对我来说,这似乎是一个分配问题,但我不确定它在哪里
__global__
void jacobi(float *diff, float *AJacobi, float *BJacobi, int *bitMask, int size)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float sum = 0.0;
int count = 0;
if(idx < size * size)
{
if(bitMask[idx] == 0)
{
//if left side of matrix
if(idx - 1 > 0 && idx % size != 0) {
sum += AJacobi[ idx - 1 ];
count++;
}
//if right side of matrix
if(idx + 1 < size * size && (idx + 1) % size != 0)
{
sum += AJacobi[ idx + 1 ];
count++;
}
//if top of matrix
if(idx - size > 0)
{
sum += AJacobi[ idx - size ];
count++;
}
//if bottom of matrix
if(idx + size < size * size)
{
sum += AJacobi[ idx + size ];
count++;
}
BJacobi[idx] = sum / count;
}
else BJacobi[idx] = AJacobi[idx];
}
//diff[idx] = BJacobi[idx] - AJacobi[idx];
}
\uuuu全局\uuuu
void jacobi(浮点*diff,浮点*AJacobi,浮点*BJacobi,整数*位掩码,整数大小)
{
int idx=blockIdx.x*blockDim.x+threadIdx.x;
浮动总和=0.0;
整数计数=0;
如果(idx0&&idx%size!=0){
sum+=AJacobi[idx-1];
计数++;
}
//如果矩阵的右边
如果(idx+10)
{
sum+=AJacobi[idx-大小];
计数++;
}
//如果矩阵的底部
如果(idx+尺寸<尺寸*尺寸)
{
sum+=AJacobi[idx+大小];
计数++;
}
BJacobi[idx]=总和/计数;
}
else BJacobi[idx]=AJacobi[idx];
}
//diff[idx]=BJacobi[idx]-AJacobi[idx];
}
在我的主要职能中
readSparceMatrix(argv[1], &matrix);
array_size = matrix.rowSize * matrix.rowSize;
//we want as many or more threads then data.
dimGrid = array_size / THREADS + 1;
dimBlock = THREADS;
// ---------------------- START ALLOCATION OF DEVICE MEMEORY
err = cudaMalloc( (void**)&diff, array_size * sizeof(float));
if (err != cudaSuccess) {
fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMalloc( (void**)&AJacobi, array_size * sizeof(float) );
if (err != cudaSuccess) {
fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMalloc( (void**)&BJacobi, array_size * sizeof(float) );
if (err != cudaSuccess) {
fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMalloc( (void**)&MaxDiffTree, array_size * sizeof(float) );
if (err != cudaSuccess) {
fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMalloc( (void**)&bitMask, array_size * sizeof(int) );
if (err != cudaSuccess) {
fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
exit(1);
}
// ---------------------- START INTITILIZATION OF DEVICE MEMERY
err = cudaMemset(diff, 1.0, array_size * sizeof(float));
if (err != cudaSuccess) {
fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMemset(BJacobi, 0.0, array_size * sizeof(float));
if (err != cudaSuccess) {
fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMemset(MaxDiffTree, 0.0, array_size * sizeof(float));
if (err != cudaSuccess) {
fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMemcpy(AJacobi, matrix.data, array_size * sizeof(float) ,cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
exit(1);
}
err = cudaMemcpy(bitMask, matrix.mask, array_size * sizeof(int) ,cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
exit(1);
}
// ---------------------- START MAIN JACOBI LOOP
//while(MaxDiff > delta){
jacobi<<<dimGrid, dimBlock>>>(diff, AJacobi, BJacobi, bitMask, matrix.rowSize);
readSparceMatrix(argv[1],&matrix);
数组_size=matrix.rowSize*matrix.rowSize;
//我们需要和数据一样多的线程。
dimGrid=阵列大小/线程数+1;
dimBlock=螺纹;
//-------------------------开始设备内存的分配
err=cudamaloc((void**)和diff,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(标准,“cudamaloc:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudamaloc((void**)和AJacobi,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(标准,“cudamaloc:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudaMalloc((void**)和BJacobi,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(标准,“cudamaloc:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudamaloc((void**)和MaxDiffTree,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(标准,“cudamaloc:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudamaloc((void**)和位掩码,数组大小*sizeof(int));
if(err!=cudaSuccess){
fprintf(标准,“cudamaloc:%s\n”,cudaGetErrorString(err));
出口(1);
}
//-------------------------开始设备内存的初始化
err=cudaMemset(差异,1.0,数组大小*sizeof(浮点));
if(err!=cudaSuccess){
fprintf(stderr,“cudaMemcpy:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudaMemset(BJacobi,0.0,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(stderr,“cudaMemcpy:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudaMemset(MaxDiffTree,0.0,数组大小*sizeof(float));
if(err!=cudaSuccess){
fprintf(stderr,“cudaMemcpy:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudaMemcpy(AJacobi,matrix.data,数组大小*sizeof(float),cudaMemcpyHostToDevice);
if(err!=cudaSuccess){
fprintf(stderr,“cudaMemcpy:%s\n”,cudaGetErrorString(err));
出口(1);
}
err=cudaMemcpy(位掩码、matrix.mask、数组大小*sizeof(int)、cudaMemcpyHostToDevice);
if(err!=cudaSuccess){
fprintf(stderr,“cudaMemcpy:%s\n”,cudaGetErrorString(err));
出口(1);
}
//-------------------------启动主雅可比回路
//while(MaxDiff>delta){
jacobi(diff、AJacobi、BJacobi、位掩码、矩阵行大小);
所以这实际上是一个简单的错误,我花了很长时间试图解决这个问题。之所以出现这个问题,是因为我有更多的线程,而不是数据。因此,我有线程索引超出了数组的界限。我的代码中的第一个if语句是为了检查这个问题,但我的diff赋值超出了界限在if检查下移动diff语句解决了我的问题
if(idx < size * size){
if(bitMask[idx] == 0){
//if left side of matrix
if(idx - 1 > 0 && idx % size != 0) {
sum += src[ idx - 1 ];
count++;
}
//if right side of matrix
if(idx + 1 < size * size && (idx + 1) % size != 0)
{
sum += src[ idx + 1 ];
count++;
}
//if top of matrix
if(idx - size > 0)
{
sum += src[ idx - size ];
count++;
}
//if bottom of matrix
if(idx + size < size * size)
{
sum += src[ idx + size ];
count++;
}
dst[idx] = sum / count;
}
else dst[idx] = src[idx];
diff[idx] = dst[idx] - src[idx];
}
if(idx0&&idx%size!=0){
sum+=src[idx-1];
计数++;
}
//如果矩阵的右边
如果(idx+10)
{
sum+=src[idx-大小];
计数++;
}
//如果矩阵的底部
如果(idx+尺寸<尺寸*尺寸)
{
sum+=src[idx+大小];
计数++;
}
dst[idx]=总和/计数;
}
else dst[idx]=src[idx];
diff[idx]=dst[idx]-src[idx];
}
我用您的代码构建了一个简单的程序,没有发现任何明显的数据问题。来自第二个内核过程的数据与来自第一个内核过程的数据完全不同。您可能想展示如何运行第二个内核过程。您交换了输入和输出矩阵吗?此外,您正在传递浮点point值设置为,这是不合适的。cudaMemset将每个字节分别设置为在第二个参数中指定的int值。在我的测试中,对内核生成的AJacobi和BJacobi数据进行注释与否并没有任何区别。我刚刚发现了问题所在。我有更多线程