尝试创建一个简单的RGB到灰度的项目。对不起,奇怪的图书馆,我的教授拒绝更新我们学校的服务器,我的家用电脑也没有英伟达卡。
#include <stdlib.h>
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <math.h>
#include <string.h>
//Define and include supporting documentation.
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define BLOCK_SIZE 16
__global__ void ConvertToGrayScale(unsigned char *image,unsigned char *grayimage, int height,int width,int channel,int gray_channel){
int col = threadIdx.x + blockIdx.x * blockDim.x;
int row = threadIdx.y + blockIdx.y * blockDim.y;
if(row >= height || col >= width) return;
unsigned char red=0, green=0, blue=0;
int imageposition = row*width + col;
int grayimageposition = row*width + col;
imageposition = imageposition*channel;
//grayimageposition = imageposition*gray_channel;
red = image[imageposition];
green = image[imageposition+1];
blue = image[imageposition+2];
grayimage[grayimageposition] = (uint8_t)(red*0.3+green*0.59+blue*0.11);
//leave the last channel of the image the same as the grey
if(channel==4){
grayimage[grayimageposition + 1] = image[imageposition + 3];
}
//grayimage = image;
}
int main(int argc, char *argv[]){
// width height and nbr of channels for image
int width, height, channel;
//Handle Input Image
if (argc != 2){
printf("Usage: ./hw5 'image.jpg'n");
exit(1);
}
//Load our image into a 1D array which is a linearized 2D grid where each
//position has a pixel RGB value. so (x,y).(R,G,B)
unsigned char *image = stbi_load(argv[1] , &width, &height, &channel, 0);
if (image == NULL){
printf("Could not load image.n");
exit(1);
}
//If the jpeg image has a 4th channel due to formating create this channel
//in the grey scale image also
int gray_channel;
if (channel == 4){
gray_channel = 2;
}else{
gray_channel = 1;
}
//Define size of our image matrices
int graybytes = width*height*gray_channel*sizeof(unsigned char);
int colorbytes = width*height*channel*sizeof(unsigned char);
unsigned char *imagegray;
imagegray = (unsigned char*)malloc(graybytes*gray_channel);
unsigned char* d_image;
unsigned char* d_imagegray;
cudaMalloc((void**)&d_image,colorbytes);
cudaMalloc((void**)&d_imagegray, graybytes);
cudaMemcpy(d_image, image, colorbytes, cudaMemcpyHostToDevice);
cudaMemcpy(d_imagegray, imagegray, graybytes, cudaMemcpyHostToDevice);
if(!imagegray){
printf("Could not allocate memory for the Gray Scale Image.n");
exit(1);
}
if(!image){
printf("Could not allocate memory for the Gray Scale Image.n");
exit(1);
}
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGrid((width/dimBlock.x)+1, (height/dimBlock.y)+1);
ConvertToGrayScale<<<dimGrid, dimBlock>>>(d_image,d_imagegray,height,width,channel,gray_channel);
cudaMemcpy( image, d_image, colorbytes*channel, cudaMemcpyDeviceToHost);
cudaMemcpy( imagegray, d_imagegray, graybytes*channel, cudaMemcpyDeviceToHost);
cudaThreadSynchronize();
cudaGetLastError();
char grey_name[30] = "gray_scale_";
// stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality)
stbi_write_jpg(strcat(grey_name,argv[1]), width, height, gray_channel, imagegray, 100);
char color_name[30] = "color_scale_";
// stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality)
stbi_write_jpg(strcat(color_name,argv[1]), width, height, channel, image, 100);
free(imagegray);
stbi_image_free(image);
cudaFree(d_image);
cudaFree(d_imagegray);
return 0;
}
所以我的输出是垃圾静态的。我相信我已经把这个问题归结为我如何来回传递数据。当我尝试使用cuda-memcheck
进行故障排除时,我会两次出现以下错误。
程序命中cudaErrorInvalidValue(错误11(,原因是";无效参数";对cudaMemcpy的CUDA API调用。
我看不出我做错了什么。我还尝试使用cudaMallocManaged,而不是手动传递数据,这给了我一个黑色方块。
我看不出我做错了什么。
当我尝试使用
cuda-memcheck
进行故障排除时,我会两次出现以下错误。
由于";无效参数";对cudaMemcpy的CUDA API调用。
您已经为d_image
:分配了colorbytes
的大小
cudaMalloc((void**)&d_image,colorbytes);
^^^^^^^^^^
但您想从中转移colorbytes*channel
的大小吗?
cudaMemcpy( image, d_image, colorbytes*channel, cudaMemcpyDeviceToHost);
^^^^^^^^^^^^^^^^^^
您已经为d_imagegray
:分配了graybytes
的大小
cudaMalloc((void**)&d_imagegray, graybytes);
^^^^^^^^^
但是你想从中转移graybytes*channel
的大小吗?
cudaMemcpy( imagegray, d_imagegray, graybytes*channel, cudaMemcpyDeviceToHost);
^^^^^^^^^^^^^^^^^
这两个看起来都不对。