Trying to create a simple RGB to grayscale project. Excuse the weird library, my professor refuses to update our school server, and my home computer doesn't have a Nvidia card.
#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;
}
So my output is a trash static. I believe I have isolated the issue down to how I am passing the data back and forth. When I try to trouble shoot with cuda-memcheck
I get the below error twice.
Program hit cudaErrorInvalidValue (error 11) due to "invalid argument" on CUDA API call to cudaMemcpy.
I can't see what I'm doing incorrect. I also tried using cudaMallocManaged instead of manually passing the data and that just gave me a black square.