From 106b2a76b22c5a0d1ed5a8d2282f92c51e7ca0bc Mon Sep 17 00:00:00 2001 From: Brandon Rodriguez <brodriguez8774@gmail.com> Date: Sat, 24 Apr 2021 13:32:10 -0400 Subject: [PATCH] Correct CUDA thread generation and create color manipulation test functions --- part_1/image.cu | 139 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 13 deletions(-) diff --git a/part_1/image.cu b/part_1/image.cu index 3b1c01d..87afa26 100644 --- a/part_1/image.cu +++ b/part_1/image.cu @@ -159,6 +159,120 @@ __global__ void cuda_alternating_blocks(unsigned long total_pixels, unsigned lon } } + +/** + * Updates image to increase percieved value of red in image. + * Purely for testing purposes. + */ +__global__ void cuda_increase_red(unsigned long total_pixels, unsigned long chunk_size, int chunk_counter, Image::PixelStruct* pixel_arr) { + // Calculate current index. + unsigned long pixel_index = blockIdx.x * blockDim.x + threadIdx.x; + + // Adjust index for current chunk. + pixel_index += (chunk_size * chunk_counter); + + // Only proceed if GPU thread corresponds to a pixel in the image. Ignore all extra threads. + if (pixel_index <= total_pixels) { + + // Calculate new pixel colors. + float red = pixel_arr[pixel_index].r + 0.1f; + float green = pixel_arr[pixel_index].g - 0.1f; + float blue = pixel_arr[pixel_index].b - 0.1f; + + // Handle if colors exceed expected values. + if (red > 1.0f) { + red = 1.f; + } + if (green < 0.0f) { + green = 0.f; + } + if (blue < 0.0f) { + blue = 0.f; + } + + // Update pixel values. + pixel_arr[pixel_index].r = red; + pixel_arr[pixel_index].g = green; + pixel_arr[pixel_index].b = blue; + } +} + + +/** + * Updates image to increase percieved value of green in image. + * Purely for testing purposes. + */ +__global__ void cuda_increase_green(unsigned long total_pixels, unsigned long chunk_size, int chunk_counter, Image::PixelStruct* pixel_arr) { + // Calculate current index. + unsigned long pixel_index = blockIdx.x * blockDim.x + threadIdx.x; + + // Adjust index for current chunk. + pixel_index += (chunk_size * chunk_counter); + + // Only proceed if GPU thread corresponds to a pixel in the image. Ignore all extra threads. + if (pixel_index <= total_pixels) { + + // Calculate new pixel colors. + float red = pixel_arr[pixel_index].r - 0.1f; + float green = pixel_arr[pixel_index].g + 0.1f; + float blue = pixel_arr[pixel_index].b - 0.1f; + + // Handle if colors exceed expected values. + if (red < 0.0f) { + red = 0.f; + } + if (green > 1.0f) { + green = 1.f; + } + if (blue < 0.0f) { + blue = 0.f; + } + + // Update pixel values. + pixel_arr[pixel_index].r = red; + pixel_arr[pixel_index].g = green; + pixel_arr[pixel_index].b = blue; + } +} + + +/** + * Updates image to increase percieved value of blue in image. + * Purely for testing purposes. + */ +__global__ void cuda_increase_blue(unsigned long total_pixels, unsigned long chunk_size, int chunk_counter, Image::PixelStruct* pixel_arr) { + // Calculate current index. + unsigned long pixel_index = blockIdx.x * blockDim.x + threadIdx.x; + + // Adjust index for current chunk. + pixel_index += (chunk_size * chunk_counter); + + // Only proceed if GPU thread corresponds to a pixel in the image. Ignore all extra threads. + if (pixel_index <= total_pixels) { + + // Calculate new pixel colors. + float red = pixel_arr[pixel_index].r - 0.1f; + float green = pixel_arr[pixel_index].g - 0.1f; + float blue = pixel_arr[pixel_index].b + 0.1f; + + // Handle if colors exceed expected values. + if (red < 0.0f) { + red = 0.f; + } + if (green < 0.0f) { + green = 0.f; + } + if (blue > 1.0f) { + blue = 1.f; + } + + // Update pixel values. + pixel_arr[pixel_index].r = red; + pixel_arr[pixel_index].g = green; + pixel_arr[pixel_index].b = blue; + } +} + //endregion CUDA Methods. @@ -457,13 +571,8 @@ void Image::compute() { // We handle image in chunks, in case we're dealing with large images with more pixels than CUDA device blocks/threads. int total_image_chunks = (total_pixels / cuda_chunk_size) + 1; logger.info("Total Image Chunks: " + std::to_string(total_image_chunks)); - - // Calculate desired blocks and threads. - int cuda_device_desired_block_count = total_pixels / cuda_device_max_threads; - if (cuda_device_desired_block_count <= 0) { - cuda_device_desired_block_count = 1; - } - // TODO: Handle if desired block count exceeds device maximum count. + logger.info("Desired CUDA block count: " + std::to_string(cuda_device_max_blocks)); + logger.info("Desired CUDA thread count: " + std::to_string(cuda_device_max_threads)); // Process image by iterating over all chunks. for (int chunk_index = 0; chunk_index < total_image_chunks; chunk_index++) { @@ -476,13 +585,17 @@ void Image::compute() { cudaMemcpy(gpu_pixel_arr, pixel_arr, struct_byte_count, cudaMemcpyHostToDevice); // Run GPU kernel logic. - // cuda_alternating_pixels<<<cuda_device_desired_block_count, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, gpu_pixel_arr); + // cuda_alternating_pixels<<<cuda_device_max_blocks, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, gpu_pixel_arr); - int pixel_block_size = width / 10; - if (pixel_block_size <= 1) { - pixel_block_size = 2; - } - cuda_alternating_blocks<<<cuda_device_desired_block_count, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, pixel_block_size, width, height, gpu_pixel_arr); + // int pixel_block_size = width / 10; + // if (pixel_block_size <= 1) { + // pixel_block_size = 2; + // } + // cuda_alternating_blocks<<<cuda_device_max_blocks, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, pixel_block_size, width, height, gpu_pixel_arr); + + // cuda_increase_red<<<cuda_device_max_blocks, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, gpu_pixel_arr); + // cuda_increase_green<<<cuda_device_max_blocks, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, gpu_pixel_arr); + cuda_increase_blue<<<cuda_device_max_blocks, cuda_device_max_threads>>>(total_pixels, cuda_chunk_size, chunk_index, gpu_pixel_arr); // Synchronize all GPU computations before iterating over next chunk. cudaDeviceSynchronize(); -- GitLab