Parrot GPU Library
repository·main·Indexed 43 days ago
https://github.com/nvlabs/parrotA header-only array fusion GPU library built on NVIDIA's CCCL (Thrust/CUB). Parrot provides high-performance, GPU-accelerated operations using a chainable, lazy-evaluation API to reduce code complexity. It supports fused operations, materializing operations (reductions, scans, permutations), and includes the kp (Kernel Profiler) CLI for profiling CUDA kernels via nsys.
What's inside Parrot
- Parrot is a C++ library designed for fused array operations using CUDA and NVIDIA's CCCL libraries (Thrust/CUB). It provides GPU-accelerated operations with fused evaluation semantics, which allows you to chain multiple operations together without the performance penalty of creating unnecessary intermediate arrays in memory.
Key Features of Parrot
mainParrot provides several core capabilities for GPU-accelerated array programming:
- Implicit Fusion: Array operations are automatically fused to minimize memory bandwidth usage.
- GPU Acceleration: Leverages NVIDIA's CCCL (Thrust/CUB) for high-performance execution.
- Chainable API: Operations can be linked together in a clean, readable syntax.
- Header-only: Easy integration via
#include "parrot.hpp".
How fusion_array operations work
mainThe
fusion_arrayclass is the core of Parrot, designed for fused evaluation of array operations.Operations in Parrot are categorized by how they handle data:
- Fused Operations (Lazy): Most unary maps (like
abs,log,exp), binary maps (likeadd,times), and reshapes are lazy. They do not compute results immediately but instead build a computation graph that can be fused into a single pass when the data is eventually accessed. - Conditionally Fused Operations: Operations like
filter,where, andkeepdepend on boolean conditions. These are part of the lazy evaluation pipeline. - Materializing Operations: Certain operations require the full data to be computed and stored in memory to proceed. These include:
- Reductions:
sum,prod,max,min, etc. - Scans:
sums,prods,maxs, etc. - Permutations:
sort,sort_by. - Compactions:
rle(Run-Length Encoding). - Masked Replication:
replicate(mask_array)where the repetition pattern is variable.
- Reductions:
- Fused Operations (Lazy): Most unary maps (like
Generate and view documentation
mainTo generate documentation, you need Doxygen and optionally Sphinx (requires
pip install -r requirements.txt).- Generate Doxygen XML documentation:
doxygen Doxyfile - Build Sphinx HTML documentation:
cd docs sphinx-build -b html . build/html - View the documentation:
The output is located in
docs/build/html/. You can open it with:open docs/build/html/index.html
# Generate Doxygen doxygen Doxyfile # Build Sphinx HTML cd docs sphinx-build -b html . build/html # Open in browser open build/html/index.html- Generate Doxygen XML documentation:
Configure CUDA environment variables
mainTo ensure the build system can find CUDA, add the following to your shell configuration file (e.g.,
~/.bashrcor~/.zshrc).For standard CUDA Toolkit installations:
export CUDA_HOME=/usr/local/cuda export PATH=$CUDA_HOME/bin:$PATH export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATHFor NVIDIA HPC SDK installations:
export CUDA_HOME=/opt/nvidia/hpc_sdk/Linux_x86_64/26.5/cuda export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/26.5/compilers/bin:$PATHAfter updating your config, reload it using
source ~/.bashrc(or your respective config file).# Standard CUDA Toolkit export CUDA_HOME=/usr/local/cuda export PATH=$CUDA_HOME/bin:$PATH export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH # Reload shell source ~/.bashrcIntegrate Parrot into a CMake project
mainYou can integrate Parrot into your C++ projects using CMake's
FetchContentmodule. This method automatically downloads the Parrot library and its transitive dependencies (like CCCL) and configures the include paths.By linking your target against the
parrottarget, you automatically propagate include paths for both Parrot and CCCL, ensuring compatibility with required components like Thrust 3.2.0+.# Include FetchContent module for downloading dependencies include(FetchContent) # Fetch the official parrot library from NVlabs/parrot FetchContent_Declare( parrot GIT_REPOSITORY https://github.com/NVlabs/parrot.git GIT_TAG main GIT_SHALLOW TRUE ) # Make parrot available (also fetches CCCL transitively) FetchContent_MakeAvailable(parrot) # Link your target against parrot — this propagates both parrot # and CCCL include paths automatically target_link_libraries(my_target parrot)Run parrot tests
mainThe project uses
doctestfor unit testing. You can run tests in several ways:Run all tests via CTest:
ctestRun the main test executable directly:
./parrot_testsRun specific test categories:
./test_basic# Run all tests ctest # Or run the main test binary ./parrot_testsBuild your project with CMake
mainAfter configuring your
CMakeLists.txtwith theFetchContentsteps, build your project using standard CMake workflows. The first build will take longer as it automatically handles downloading and building Parrot and its dependencies.mkdir build && cd build cmake .. make -j$(nproc)Use Sweep mode to profile across input sizes
mainSweep mode allows you to profile implementations across a geometric range of input sizes (a 10x range) and generates a line chart comparing total kernel time against the input size $N$.
Requirements:
- The Python files being profiled must be able to accept $N$ as a command-line argument. If the argument is omitted, the script will fall back to its default value.
Workflow:
- Run the command with the
-nflag specifying the lower and upper bounds (e.g.,10Kto10M). kpwill execute the files with $N$ values at each 10x step (e.g., 10K, 100K, 1M, 10M).- Results are saved to
nsys_results/sweep_results.csv. You can use the-p(plot-only) flag later to re-generate plots without re-running the expensive profiling step.
kp -n 10K 10M max_abs_diff2Build the parrot project
mainFollow these steps to compile the project from the repository root:
- Create and enter a build directory:
mkdir -p build cd build - Configure the project with CMake:
cmake .. - Build the project using all available CPU cores:
cmake --build . -j$(nproc)
mkdir -p build && cd build cmake .. cmake --build . -j$(nproc)- Create and enter a build directory:
Prerequisites for building parrot
mainTo build and test
parrot, ensure your system meets the following requirements:- CMake: version 3.10 or higher
- C++ Compiler: Must support C++20
- NVIDIA CUDA Toolkit: version 13.0 or later
- NVIDIA GPU: Compute capability 7.0 or higher
Optional (for documentation generation):
- Python 3 with
pip(oruv) - Doxygen
Quick Start with Parrot
mainParrot is a header-only GPU library for array fusion. You can integrate it by including
parrot.hpp. It uses a chainable API that allows you to perform complex operations on arrays without manual intermediate materialization, thanks to lazy evaluation semantics.To use it, create arrays using
parrot::arrayand chain operations using standard mathematical operators.#include "parrot.hpp" int main() { // Create arrays auto A = parrot::array({3, 4, 0, 8, 2}); auto B = parrot::array({6, 7, 2, 1, 8}); auto C = parrot::array({2, 5, 7, 4, 3}); // Chain operations (B * C + A).print(); // Output: 15 39 14 12 26 }