Interactive image filtering and benchmarking in C++/CUDA with simple 2D convolution kernels. Includes CPU and GPU implementations, plus micro-benchmarks.
- CPU and CUDA implementations of 2D convolution-based filters
- Interactive CLI to choose filters and parameters
- Outputs filtered grayscale PNGs to the
datadirectory - Benchmarking utilities for CPU and GPU paths
GPU_image_filter/
benchmarking/ # Standalone CPU/GPU benchmark programs
00_cpu_conv2d_benchmark.cpp
01_gpu_conv2d_benchmark.cu
03_gpu_conv2d_pinnedConstMem_bench.cu
bin/ # Compiled binaries
build/ # Optional build artifacts
data/ # Input images and generated outputs
include/ # Public headers
00_cpu_conv2d.hpp
01_gpu_conv2d.cuh
02_gpu_conv2d_constMem.cuh
utils.hpp
lib/ # Third-party single-header libs
stb_image.h
stb_image_write.h
scripts/ # CLI entry programs
cpu_filter.cpp # CPU interactive filter
01_gpu_filter.cu # CUDA interactive filter (const memory)
src/ # Library/implementation files
cpu_conv2d.cpp
gpu_conv2d_constMem.cu
gpu_cov2d.cu # Alternate/experimental GPU kernel
utils.cpp
- For CPU build: a C++17 compiler (e.g., Clang or GCC)
- For GPU build: NVIDIA GPU and CUDA Toolkit (nvcc)
stb_image.handstb_image_write.hare bundled underlib/
Create the bin directory if it doesn’t exist:
mkdir -p binCPU (Clang/GCC):
clang++ -std=c++17 -O2 \
scripts/cpu_filter.cpp src/cpu_conv2d.cpp src/utils.cpp \
-Iinclude -Ilib -o bin/cpu_filterCUDA (nvcc):
nvcc -std=c++17 -O2 \
scripts/01_gpu_filter.cu src/gpu_conv2d_constMem.cu src/utils.cpp \
-Iinclude -Ilib -o bin/gpu_filterBenchmarks (optional):
clang++ -std=c++17 -O2 benchmarking/00_cpu_conv2d_benchmark.cpp \
src/cpu_conv2d.cpp src/utils.cpp -Iinclude -Ilib -o bin/cpu_bench
nvcc -std=c++17 -O2 benchmarking/01_gpu_conv2d_benchmark.cu \
src/gpu_conv2d_constMem.cu src/utils.cpp -Iinclude -Ilib -o bin/gpu_bench
nvcc -std=c++17 -O2 benchmarking/03_gpu_conv2d_pinnedConstMem_bench.cu \
src/gpu_conv2d_constMem.cu src/utils.cpp -Iinclude -Ilib -o bin/gpu_bench_pinnedMake sure your input image exists (e.g., put one in data/sample.png). The apps are interactive: they will prompt for the image path and for a filter.
CPU:
./bin/cpu_filter
# Enter image location: data/lena.png
# Choose a filter when prompted. Output: data/filtered_img.pngCUDA:
./bin/gpu_filter
# Enter image location: data/lena.png
# Choose a filter when prompted. Output: data/filtered_image.pngNote: The CPU program writes data/filtered_img.png, while the CUDA program writes data/filtered_image.png.
When prompted, enter one of:
Sharpen(prompts foralphain (0,1); default 0.8)High-passLow-pass(prompts foralpha; default 9.0)Gaussian(prompts foralpha; default 16.0)d_Gaussianqto quit
All filters operate on a 3×3 kernel with radius 1 and run on a grayscale version of the input image. Internally the image is padded to a square of size max(width, height) for processing, then written at the original width × height.
- CUDA build errors on macOS/Apple Silicon: CUDA is not supported; build the CPU target instead.
- Missing
stb_imagesymbols: ensure-Ilibis present and you compile the appropriate.cpp/.cufiles that includestbheaders. - Permission denied when running binaries:
chmod +x bin/*or re-createbin.
- Uses
stb_image.handstb_image_write.hby Sean Barrett (public domain / MIT-like).