C++ 使用cuda进行图像处理,图像不变

C++ 使用cuda进行图像处理,图像不变,c++,opengl,cuda,C++,Opengl,Cuda,我有以下内核 __global__ void filter(unsigned char *image, unsigned char *out, int n, int m) { int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; int offset = x + y * blockDim.x * gri

我有以下内核

   __global__ void filter(unsigned char *image, unsigned char *out, int n, int m)
    {
        int x = blockIdx.x * blockDim.x + threadIdx.x;
        int y = blockIdx.y * blockDim.y + threadIdx.y;
        int offset = x + y * blockDim.x * gridDim.x;
        int sumx, sumy, sumz, k, l;

        __shared__ float shared[16][16];

        shared[threadIdx.x][threadIdx.y] = image[offset];
            out[offset] = shared[threadIdx.x][threadIdx.y]; 

    }
我调用它就像
filter(dev_image,dev_out,n,m)

奇怪的是,即使我对内核调用进行注释并编译,图像仍然保持不变。知道为什么会这样吗?gpu上的内存不是被释放了吗

void Draw()
{
    unsigned char *image, *out;
    int n, m;
    unsigned char *dev_image, *dev_out;
    image = readppm("maskros512.ppm", &n, &m);
    out = (unsigned char*) malloc(n*m*3);
    printf("%d %d\n",n,m );
    cudaMalloc( (void**)&dev_image, n*m*3);
    cudaMalloc( (void**)&dev_out, n*m*3);
    cudaMemcpy( dev_image, image, n*m*3, cudaMemcpyHostToDevice);
    dim3 threads( 1, 256 );
    dim3 blocks( 32, 32 );
    filter<<<blocks, threads>>>(dev_image, dev_out, n, m);
    cudaMemcpy( out, dev_out, n*m*3, cudaMemcpyDeviceToHost );
    cudaFree(dev_image);
    cudaFree(dev_out);
    glClearColor( 0.0, 0.0, 0.0, 1.0 );
    glClear( GL_COLOR_BUFFER_BIT );
    glRasterPos2f(-1, -1);
    glDrawPixels( n, m, GL_RGB, GL_UNSIGNED_BYTE, image );
    glRasterPos2i(0, -1);
    glDrawPixels( n, m, GL_RGB, GL_UNSIGNED_BYTE, out );
    glFlush();
}
void Draw()
{
无符号字符*图像,*输出;
int n,m;
未签名字符*dev_image,*dev_out;
image=readppm(“maskros512.ppm”、&n和&m);
out=(无符号字符*)malloc(n*m*3);
printf(“%d%d\n”,n,m);
Cudamaloc((空白**)和开发图像,n*m*3);
Cudamaloc((void**)和dev_out,n*m*3);
cudaMemcpy(dev_image,image,n*m*3,cudamemcpyhostodevice);
dim3螺纹(1256);
dim3块(32,32);
过滤器(dev_image,dev_out,n,m);
cudaMemcpy(out,dev_out,n*m*3,cudaMemcpyDeviceToHost);
cudaFree(dev_图像);
cudaFree(dev_out);
glClearColor(0.0,0.0,0.0,1.0);
glClear(GLU颜色缓冲位);
glRasterPos2f(-1,-1);
GLDRAW像素(n,m,GL_RGB,GL_无符号字节,图像);
glRasterPos2i(0,-1);
GLDRAW像素(n,m,GL_RGB,GL_无符号字节,out);
glFlush();
}

如果只注释掉
过滤器
行,则没有任何内容填充
dev\u out
。因此,如果您随后将
dev_out
复制到
out
中,您将得到垃圾,可能是上次
dev_out
中的任何内容

这些行是不对的:

dim3 threads( 1, 256 );
dim3 blocks( 32, 32 );
您正在启动的线程块是x中的1个线程乘以y中的256个线程。这对您的内核没有意义。您的内核希望每个像素启动一个线程,并且它希望x和y中都有足够的线程数组来覆盖像素的图像空间。此外,共享内存分配需要16x16个线程块。试试这个:

dim3 threads(16,16);
dim3 blocks((n+threads.x-1)/threads.x, (m+threads.y-1)/threads.y);
此外,您的图像似乎由3字节像素组成。但是,每像素只启动一个线程。因此,您需要每像素复制3个字节,而不是一个。大概是这样的:

#define RED 0
#define GRN 1
#define BLU 2

__global__ void filter(unsigned char *image, unsigned char *out, int n, int m)
{
    int x = blockIdx.x * blockDim.x + threadIdx.x;
    int y = blockIdx.y * blockDim.y + threadIdx.y;
    int offset = x + y * blockDim.x * gridDim.x;
    // the above numbers are all pixel dimensions.  To convert to byte dimensions, 
    // we must multiply by 3
    int sumx, sumy, sumz, k, l;

    __shared__ unsigned char shared[16][16*3];

    shared[threadIdx.x][(threadIdx.y*3)+RED] = image[(offset*3)+RED]; // pick up red
    shared[threadIdx.x][(threadIdx.y*3)+GRN] = image[(offset*3)+GRN]; // pick up green
    shared[threadIdx.x][(threadIdx.y*3)+BLU] = image[(offset*3)+BLU]; // pick up blue
    out[(offset*3)+RED] = shared[threadIdx.x][(threadIdx.y*3)+RED]; 
    out[(offset*3)+GRN] = shared[threadIdx.x][(threadIdx.y*3)+GRN]; 
    out[(offset*3)+BLU] = shared[threadIdx.x][(threadIdx.y*3)+BLU]; 
}

最后,您应该正确地执行

您的内核什么都不做。(请注意,内核中没有任何东西被写入
out
,也没有任何全局内存位置。)很可能编译器正在将其优化为空函数。无论图像中发生了什么,都是代码中某些方面的结果,这些方面您没有显示出来。事实上,SO期望:“与您编写的代码问题有关的问题必须在问题本身中描述特定问题,并包括重现问题的有效代码。请参阅SSCCE.org以获取指导。”投票关闭-您还没有提供SSCCE.org代码。即使您现在向内核添加了一行代码,将
写入
,但如果不显示完整的代码,仍然无法解释发生了什么。@RobertCrovella我添加了调用过滤器的my Draw函数,奇怪的是,即使我对“过滤器”行进行注释,图像也不会改变。