Matrix CUDA矩阵乘法-又一次

Matrix CUDA矩阵乘法-又一次,matrix,cuda,multiplication,Matrix,Cuda,Multiplication,我觉得制作一个已经有10个同名的论坛帖子有点糟糕,但是在检查完所有的帖子之后,再加上周围的大多数指南,我仍然无法找出问题所在 我有一个char数组[40090 ] [11 ],我想对它的两个元素的每个可能组合进行自定义操作(我把整个11字节的堆看成一个元素)。我知道这是一种矩阵乘法,矩阵是一列一行 根据SDK手册,我考虑每个输出元素有一个线程。由于40090=19*2110,我使用: dim3 threadsperblock(19,19); dim3 blocksingrid(2110,2110

我觉得制作一个已经有10个同名的论坛帖子有点糟糕,但是在检查完所有的帖子之后,再加上周围的大多数指南,我仍然无法找出问题所在

我有一个char数组[40090 ] [11 ],我想对它的两个元素的每个可能组合进行自定义操作(我把整个11字节的堆看成一个元素)。我知道这是一种矩阵乘法,矩阵是一列一行

根据SDK手册,我考虑每个输出元素有一个线程。由于40090=19*2110,我使用:

dim3 threadsperblock(19,19);
dim3 blocksingrid(2110,2110);
xkernel<<<blocksingrid, threadsperblock>>>(dev_b2);
dim3螺纹锁紧(19,19);
dim3 blocksingrid(21102110);
xkernel(dev_b2);
问题1:这样可以吗

好吧,那么,我想我完全遵循了SDK的maunal示例(不是使用共享内存的示例)。然而,每当我胆敢对数据进行我想要的操作的一部分时,我就会得到一个巨大的无用错误30:未知错误。那么,问题2:我做错了什么?注意:忽略内核并没有在任何地方保存任何东西

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctime>
#include <stdio.h>
using namespace std;

cudaError_t cudafunct(void);
__global__ void xkernel(char * dev_b2);
__device__ unsigned char typecheck(unsigned char type1,unsigned char type2);


#define b2c 40090
unsigned char block2[b2c][11];//
//unsigned int i,b1,b2,counter=0;//Block(2),Piece,Rotation,Type(of block2),InterconnectinTriangle
//unsigned char *block4,type=0;
ofstream ofile;




int main()
{
     ifstream block2file("2.blk",ios::binary);
     block2file.read((char*)(&block2),b2c*11);
     block2file.close();
     //block4=new unsigned char[200000000];//200MB will do, better than doing constant reallocs

    cudaError_t cudaStatus = cudafunct();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudafunct failed!");
        system("PAUSE");
        return 1;
    }
    /*

    // cudaDeviceReset must be called before exiting in order for profiling and
    // tracing tools such as Nsight and Visual Profiler to show complete traces.
    cudaStatus = cudaDeviceReset();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceReset failed!");
        return 1;
    }*/
     cout<<"Sequence end. Saving to file...\n";     
     //ofile.open("blk4.et2",ios::binary);
     //ofile.write((char*)block4,17*counter);   
     //ofile.close(); 
     int t=clock();
     //cout<<"\nFound a total of "<<counter<<" block4s.\nTime elapsed: "<<t<<" clocks / "<<(double)t/(double)CLOCKS_PER_SEC<<" seconds\n";
     system("PAUSE");
}

// Helper function for using CUDA to add vectors in parallel.
cudaError_t cudafunct(void)
{
    char *dev_b2 = 0;
    cudaError_t cudaStatus;

    cudaStatus = cudaMalloc((void**)&dev_b2, sizeof(block2));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    cudaStatus = cudaMemcpy(dev_b2, block2, sizeof(block2), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

    dim3 threadsperblock(19,19);
    dim3 blocksingrid(2110,2110);
    xkernel<<<blocksingrid, threadsperblock>>>(dev_b2);

    // cudaDeviceSynchronize waits for the kernel to finish, and returns
    // any errors encountered during the launch.
    cudaStatus = cudaDeviceSynchronize();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching xkernel!\n", cudaStatus);
        goto Error;
    }
    /*
    // Copy output vector from GPU buffer to host memory.
    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }*/

Error:
    cudaFree(dev_b2);
    return cudaStatus;
}


__global__ void xkernel(char *dev_b2)
{
        int i = blockIdx.x * blockDim.x + threadIdx.x; 
        int j = blockIdx.y * blockDim.y + threadIdx.y;
        /*for(int k=0;k<11;k++)
        {
            lb2[0][k]=dev_b2[i*b2c+k];
            lb2[1][k]=dev_b2[j*b2c+k];
        }*/
        int b00;
        b00=dev_b2[i*b2c];

        //int type=typecheck(dev_b2[i*b2c+4],dev_b2[j*b2c+4]);
        //if(!j && !(i % 100))cout<<setw(6)<<i<<" / "<<jc<<" ("<<setw(10)<<(float)100*i/jc<<" % )"<<endl;     
        /*if(
            (dev_b2[i*b2c+7]!=dev_b2[j*b2c+9])||//SW~NW     
            (dev_b2[i*b2c+6]!=dev_b2[j*b2c+10])//SE~NE                                                                                         
        ) return;
        if( (type=typecheck(dev_b2[i*b2c+4],dev_b2[j*b2c+4]) ) ==255) return;*/
        /*if(
            (dev_b2[i*b2c+0]==dev_b2[j*b2c+0])||//1st=3rd
            (dev_b2[i*b2c+0]==dev_b2[j*b2c+2])||//1st=4th
            (dev_b2[i*b2c+2]==dev_b2[j*b2c+0])||//2nd=3rd
            (dev_b2[i*b2c+2]==dev_b2[j*b2c+2])//2nd=4th
        ) return;*/
        /*
        *(block4+counter*17+0)=b2[i][0];//1st piece
        *(block4+counter*17+1)=b2[i][1];//1st rotation
        *(block4+counter*17+2)=b2[i][2];//2nd piece
        *(block4+counter*17+3)=b2[i][3];//2nd rotation
        *(block4+counter*17+4)=b2[j][0];//3rd piece
        *(block4+counter*17+5)=b2[j][1];//3rd rotation
        *(block4+counter*17+6)=b2[j][2];//4th piece
        *(block4+counter*17+7)=b2[j][3];//4th rotation
        *(block4+counter*17+8)=type;
        *(block4+counter*17+9)=b2[i][5];//Right frame colours, down->up
        *(block4+counter*17+10)=b2[j][5];
        *(block4+counter*17+11)=b2[j][6];//Up frame colours, right->left
        *(block4+counter*17+12)=b2[j][7];
        *(block4+counter*17+13)=b2[j][8];//Left frame colours, up->down
        *(block4+counter*17+14)=b2[i][8];
        *(block4+counter*17+15)=b2[i][9];//Down frame colours, left->right
        *(block4+counter++*17+16)=b2[i][10];*/
}  



__device__ unsigned char typecheck(unsigned char type1,unsigned char type2)
{//Warning! Previous error! First partenthesis is t*2* = upper piece!
       if( (type1==4) && (type2==0) ) return  0;  
       if( (type1==6) && (type2==1) ) return  1;  
       if( (type1==2) && (type2==6) ) return  2;  
       if( (type1==3) && (type2==4) ) return  3;  
       if( (type1==4) && (type2==4) ) return  4;  
       if( (type1==8) && (type2==5) ) return  5;  
       if( (type1==6) && (type2==6) ) return  6;  
       if( (type1==7) && (type2==8) ) return  7;  
       if( (type1==8) && (type2==8) ) return  8;  
       if( (type1==9) && (type2==8) ) return  9;  
       if( (type1==10) && (type2==8) ) return  10;  
       if( (type1==8) && (type2==11) ) return  11;  
       if( (type1==8) && (type2==12) ) return  12;  
       if( (type1==8) && (type2==13) ) return  13;  
       return 255;
}
#包括“cuda_runtime.h”
#包括“设备启动参数.h”
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
cudaError_t cudafunt(无效);
__全局无效xkernel(char*dev_b2);
__设备\无符号字符类型检查(无符号字符类型1,无符号字符类型2);
#定义b2c 40090
未签名字符块2[b2c][11]//
//无符号整数i,b1,b2,计数器=0//块(2),块,旋转,类型(块2),互连轨道
//无符号字符*block4,类型=0;
气流;
int main()
{
ifstreamblock2file(“2.blk”,ios::binary);
块2文件读取((字符*)(&block2),b2c*11);
block2file.close();
//block4=newunsignedchar[200000000];//200MB就可以了,比使用常量realloc要好
cudaError_t cudaStatus=cudafunt();
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudafunt失败!”);
系统(“暂停”);
返回1;
}
/*
//必须在退出之前调用cudaDeviceReset,以便进行分析和
//跟踪工具,如Nsight和visualprofiler,用于显示完整的跟踪。
cudaStatus=cudadeviceset();
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaDeviceReset失败!”);
返回1;
}*/

我感觉你从你的
dev_b2
数组中读到的内容超出了范围。
blockIdx.x
[0..2110]
的范围内,因此变量
i
[0..23210]
的范围内。但是,然后将其与
b2c
相乘。 因此,您从中读取的最高地址将是
b2c*23210=930488900


但是
dev_b2
的大小只有
b2c*11=440990

我感觉您从
dev_b2
数组中读取的内容超出了范围。
blockIdx.x
[0..2110]
的范围内,因此变量
i
[0..23210]
的范围内。但是,然后将其与
b2c
相乘。 因此,您从中读取的最高地址将是
b2c*23210=930488900


但是
dev_b2
的大小只有
b2c*11=440990

你确定CUDA驱动程序正常工作吗?请测试SDK中的带宽测试或设备查询。带宽测试正常。你确定CUDA驱动程序正常工作吗?请测试SDK中的带宽测试或设备查询。带宽测试正常工作。我不认为这些是范围。正如我所发布的,blockIdx.x在2110的范围内,线程等效值是19。另一件有趣的事情:我发布的代码实际上是有效的。但是,如果不是int b00,我会生成int b[0][0],并尝试将相同的值赋给b[0][0],这就是我得到错误的地方。如果您发布了实际失败的代码,可能会更好。我不太确定您所说的“如果在内核中有int b00;b00=dev_b2的点上,而不是int b00,我生成int b[0][0]”是什么意思[i@b2c];我将其更改为int b[1][1];b[0][0]=dev_b2[I*b2c];它的编译和运行方式与更改前相同。此外,threadsperblock建议为32的倍数,即扭曲大小。@user1058795是的,我将b2x与gridDim.x混合在一起,后者稍小一些。但即使如此,您还是超出了范围。我用数字修复了我的响应。您发布的代码实际上没有任何作用,而且CUDA将通过消除死代码生成一个空内核。@RobertCrovella做了与您提到的完全相同的更改,我得到了错误。如果您说32的倍数更好,我会这样做;但首先,我希望程序实际运行,这就是为什么为了方便起见,我使用了数据计数的除数。@CygnusX1我为自己如此愚蠢而感到羞愧.我实际上想用另一个维度11相乘,而不是b2c。我想没有办法使用原始的括号对,对吧?像dev_b2[I][0]?总之,问题解决了,非常感谢!我不认为这些是范围。正如我发布的,blockIdx.x在2110的范围内,线程等效值是19。另一件有趣的事情:我发布的代码实际上是有效的。但是,如果我不使用int b00,而是使用int b[0][0],并尝试将相同的值赋给b[0][0],这就是我得到错误的地方。如果您发布了实际失败的代码,可能会更好。我不太确定您所说的“如果在内核中有int b00;b00=dev_b2的点上,而不是int b00,我生成int b[0][0]”是什么意思[i@b2c];我将其更改为int b[1][1];b[0][0]=dev_b2[I*b2c];它的编译和运行方式与更改前相同。此外,threadsperblock建议为32的倍数,即扭曲大小。@user1058795是的,我将b2x与gridDim.x混合在一起,后者稍小一些。但即使如此,您还是超出了范围。我用数字修复了我的响应。您发布的代码实际上没有任何作用,而且CUDA将通过