Examples#

All example source code lives under example/nppdx/ in the NPPDx repository. Examples are grouped by topic in numbered directories, plus a clang_ptx/ directory for the Clang device-only PTX build. Each sample is a complete CUDA program that builds with the example CMake project. New users should start with 00_introduction/introduction_example.cu together with Image Processing Using NPPDx.

Building and running examples#

See Installation Guide for the full set of CMake options (including the Clang PTX build). From the repository root:

cmake -S "${NPPDX_ROOT}/example/nppdx" -B build-nppdx-examples \
      -DNPPDX_BUILD_CUDA_EXAMPLES=ON \
      -DNPPDX_CUDA_ARCHITECTURES=80-real

cmake --build build-nppdx-examples --target nppdx_examples
ctest --test-dir build-nppdx-examples --output-on-failure

Each example CMake target is named <example-dir>_<example-name> (for example 03_area_operation_box_filter), but the built executable keeps just the source file name and is written under build-nppdx-examples/<example-dir>/<example-name>:

./build-nppdx-examples/00_introduction/introduction_example
./build-nppdx-examples/04_resize/fused_resize

Run cmake --build build-nppdx-examples --target help to list every generated target.

Set NPPDX_BUILD_CLANG_PTX_EXAMPLES=ON and NPPDX_BUILD_CUDA_EXAMPLES=OFF (with CMAKE_CXX_COMPILER=clang++) to build the Clang PTX example under clang_ptx/ instead; see clang_ptx/ below and Clang device compilation in Installation Guide.

Some examples are conditional:

  • box_filter, box_filter_fused_conversion, gaussian_blur_fused_conversion, sharpen_fused_conversion, and median_fused_conversion optionally compare output and performance against NPP when the CUDA NPP SDK is available at configure time.

  • clang_ptx/fused_resize requires NPPDX_BUILD_CLANG_PTX_EXAMPLES=ON and Clang 21 or newer as CMAKE_CXX_COMPILER; it is not part of the default CUDA example build.

Table 1 Example overview#

Group

Example

Description

Introduction

introduction_example

Register-only API. Minimal ingest/exgest round-trip: packed RGB24 into float registers, then back out to RGB24. Start here.

Introduction

introduction_example_shared_memory

Shared-memory API. Same RGB24-to-RGB24 flow using shared_memory::TileStorage and storage traits instead of registers.

Introduction

texture_example

Texture buffer (CUDA array) hardware accelerated ingest/exgest. Texture ingest paired with pointer exgest, and pointer ingest paired with surface exgest, both for RGB24.

Color Conversion

image_conversion_example

Register-only API. RGB24-to-YUV420p and YUV420p-to-RGB24 round-trip through color_convert, with sample pixels and error stats.

Color Conversion

limited_range_example

Register-only API. Full-range/limited-range affine remapping (affine_channel_map) for RGB and YUV BT.709 4:4:4, at 8-bit and 10-bit depth.

Fused Pointwise

rgb_gamma_example

Register-only API. Ingest RGB24, apply forward and/or inverse gamma (SDR, HLG, PQ), exgest RGB24, with round-trip verification.

Area process

box_filter

Shared-memory API with a halo. Box blur only: ingest RGB24 with halo, blur, exgest RGB24. See Box blur.

Area process

box_filter_fused_conversion

Shared-memory API with a halo. Box blur fused with an in-place RGB-to-YUV BT.601 color_convert, exgest YUV422p.

Area process

gaussian_blur_fused_conversion

Same fused area-plus-pointwise pattern as above, using Gaussian blur.

Area process

median_fused_conversion

Same fused area-plus-pointwise pattern as above, using a median filter.

Area process

sharpen_fused_conversion

Same fused area-plus-pointwise pattern as above, using a 3x3 additive (Rosenfeld Laplacian-style) sharpen kernel.

Resize

resize_example

Shared-memory API with a resize-dependent halo. Resize only; output geometry different from input; validated against a CPU reference.

Resize

fused_resize

Shared-memory API. Box blur, resize, and an in-place RGB-to-YUV BT.601 color_convert fused in one kernel.

Clang PTX

clang_ptx/fused_resize

Device-only PTX build of the fused blur-resize-convert kernel, launched from a C++ host program through the CUDA Driver API.

00_introduction/#

Basic ingest/exgest; Register-only API versus Shared-memory API; hardware accelerated texture/surface I/O.

  • introduction_example.cu: Register-only API. Smallest complete NPPDx program and the best place to start (see Image Processing Using NPPDx). Ingest packed RGB24 into float registers, then exgest straight back to RGB24 – same packing format in and out. Shows how ingest and exgest are specified, how compile-time launch traits are queried, and how the kernel is launched.

  • introduction_example_shared_memory.cu: Shared-memory API. Same RGB24-to-RGB24 round trip through shared memory instead of registers. Builds a shared_memory::TileStorage for the tile and uses storage traits (input_storage_of_t, compute_total_tile_storage) to size it – the pattern every shared-memory example after this one builds on.

  • texture_example.cu: hardware accelerated texture ingest and exgest for CUDA arrays instead of pitch-linear pointers. Two passes: texture ingest (tex2D) with pitch-linear pointer exgest, then pointer ingest with surface exgest (surf2Dwrite). Pattern for consuming or producing texture/surface buffers from graphics APIs and NVENC/NVDEC without an extra copy to pitch-linear memory.

01_color_conversion/#

Color and packing-format conversion using the Register-only API.

  • image_conversion_example.cu: Register-only API. One kernel per direction: ingest packed RGB24 or YUV420p, color_convert on the float tile, exgest to the other packing. The sample runs RGB to YUV, then YUV to RGB round-trip, prints sample pixels, and reports error stats. Clipping to the representable range of the output packed format happens at exgest (standard NPPDx behavior).

  • limited_range_example.cu: Register-only API. Applies affine_channel_map with ToLimitedLuma / FromLimitedLuma (and the matching chroma variants) to move samples between full range and limited (studio) range, for both RGB and YUV BT.709 4:4:4, at 8-bit and 10-bit depth. Verifies that every output sample lands inside the target range.

02_fused_pointwise/#

Fused kernels with pointwise steps between ingest and exgest.

  • rgb_gamma_example.cu: Register-only API. Ingest RGB24, apply gamma forward and/or inverse (SDR, HLG, and PQ transfer functions) in place on the register tile, then exgest RGB24. Forward-plus-inverse pairs verify round-trip correctness; forward-only cases write result images for inspection. Smallest example of an in-place Function<function::gamma> on a register tile.

03_area_operation/#

Neighborhood (area) steps and fused kernels that combine an area process with pointwise color conversion. These examples use the Shared-memory API, halos (MemoryHalo / CumulativeHalo, see Halo operators), and dual TileStorage buffers so intermediate results stay on-chip without round-trips to global memory.

  • box_filter.cu: Area-process baseline. Ingest RGB24 with a halo into a shared-memory tile, apply a box blur, and exgest RGB24 – no other step between ingest and exgest. Shows the Shared-memory API with one intermediate neighborhood step.

  • box_filter_fused_conversion.cu: Fuses that same box blur with an in-place RGB-to-YUV BT.601 color_convert before exgesting YUV422p. Canonical area-plus-pointwise fused kernel on the Shared-memory API, and the template the remaining three examples in this directory follow.

  • gaussian_blur_fused_conversion.cu: Same fused-kernel structure as box_filter_fused_conversion, with Gaussian blur in place of box blur.

  • median_fused_conversion.cu: Same structure with a median filter.

  • sharpen_fused_conversion.cu: Same structure with a 3x3 additive Rosenfeld Laplacian-style sharpen.

These are good examples of working with halos and TileStorage buffers when a fused kernel includes a single neighborhood step.

04_resize/#

Resize with shared-memory tiles, halos, and output geometry different from input.

  • resize_example.cu: Resize only. Ingest RGB24 with a resize-dependent halo, perform the resize, and exgest RGB24 at the output width and height. Uses separate input, intermediate, and output TileStorage buffers (slice_into_tile_storage) so those buffers stay distinct. This example is a 2:1 downscale (312x376 to 156x188) with bilinear interpolation, validated against a CPU reference. Because resize changes output tile geometry, query the resize-related traits (for example nppdx::output_storage_of_t<Resize>) and set grid dimensions from the output size, not the input.

  • fused_resize.cu: Fused kernel with resize. Ingest RGB24, box blur, a 2x upscale resize, and an in-place RGB-to-YUV BT.601 color_convert, then exgest YUV422p (312x376 to 624x752 in the default configuration). Shows resize composed with area and pointwise steps the same way 03_area_operation/ fuses blur and color conversion.

clang_ptx/#

Device-only PTX built with Clang (not nvcc), loaded from a host C++ driver via the CUDA Driver API.

  • fused_resize (fused_resize_device.cu + fused_resize.cpp): Same fused blur \(\rightarrow\) resize \(\rightarrow\) convert kernel as 04_resize/fused_resize.cu, compiled to PTX with Clang and launched from the host executable. Shows that NPPDx device code runs outside nvcc.

Requires NPPDX_BUILD_CLANG_PTX_EXAMPLES=ON, Clang 21+ as CMAKE_CXX_COMPILER, and NPPDX_CLANG_PTX_COMPAT_INCLUDE_DIR. Full configure steps are under Clang device compilation in Installation Guide.

Per-example walkthrough pages may be added later. Until then, use the sources above together with Image Processing Using NPPDx, Traits, Operators, and Processing overview.