NVVPU Toolchain#

The NVVPU toolchain is the NVIDIA-developed LLVM-based compiler toolchain included in the core PVA SDK.

Selecting NVVPU#

Install NVVPU with the platform workflow in Installation, or directly with pva-sdk-2.10-vpu-dev-nvvpu. NVVPU is selected automatically when ASIP Programmer is absent. If both toolchains are installed, force NVVPU with:

cmake -DPVA_USE_NVVPU=ON ...

When selected, NVVPU is used for building VPU device code. Device libraries and test packages are built with an nvvpu suffix to distinguish them from Chess-compiled artifacts.

Migrating from ASIP Programmer#

NVVPU accepts most code written for ASIP Programmer, including most Chess C/C++ extensions. Some differences are intentional design decisions. Review the following before migrating existing VPU code.

Area

Difference

Migration action

Chess annotations

Most chess_* annotations are accepted but have no effect.

Review code that depends on scheduling annotations; see Chess C/C++ code extensions.

Scheduling barriers

chess_separator and chess_separator_scheduler are ignored.

Use the mem_fence intrinsic or a function call boundary to enforce memory ordering.

Linker configuration

NVVPU uses lld linker scripts. ASIP Programmer uses BCF files. The formats are incompatible.

Port BCF customizations to a linker script; see NVVPU Linker Scripts.

Mixed-toolchain linking

Object files built with NVVPU and ASIP Programmer cannot be linked into one executable.

Build every object file in an executable with the same toolchain.

Debugging

NVVPU binaries cannot be debugged with ChessDE.

Use LLDB; see VPU Debugging.

Instruction endianness

NVVPU emits little-endian instruction words. ASIP Programmer emits big-endian instruction words.

None when using the PVA SDK build system.

Instruction endianness#

NVVPU generates instruction words in the native little-endian hardware encoding. The PVA SDK build system converts NVVPU output to big-endian with pvasdkFlipEndian.py so the runtime can load it. Custom build systems must perform the same conversion. In a future release, the runtime will accept little-endian instructions natively.

Chess C/C++ code extensions#

Most Chess annotations are silently ignored when compiling with NVVPU. Existing code compiles without modification, but Chess-specific optimization hints do not take effect.

The following annotations are recognized and respected by NVVPU:

Annotation

NVVPU Behavior

Notes

chess_storage(...)

Same as Chess

Memory type (DMb, DRAM, RAM_Ab, etc.), alignment, and segment are fully respected. Generates appropriate ELF section placement.

chess_segment(...)

Same as Chess

Custom segment names are applied. Used in conjunction with chess_storage.

chess_unroll_loop / nvvpu_unroll

Same intent, LLVM unroller

Loop unroll hints are converted to LLVM loop metadata. The LLVM unroller may make different decisions than Chess for partial unroll factors.

chess_alignof(...)

Same as Chess

Maps directly to standard C++ alignof.

chess_used

Same as Chess

Used to indicate a variable is used and should not be eliminated.

chess_may_alias

Same intent

Converted to clang attribute may_alias.

chess_loop_range

Same intent

Lower bound is respected and used to eliminate loop guards.

Other chess_* annotations (such as chess_guard, chess_memory_fence, chess_protect_access, chess_prepare_for_pipelining, chess_separator, chess_no_hw_loop, property, etc.) are defined as preprocessor macros that expand to no-ops or identity expressions. They will not cause compilation errors, but they have no effect on code generation.

Warning

Ignoring some annotations can change program behavior, not only performance. For example, NVVPU may reorder memory accesses across chess_separator or chess_separator_scheduler. Because AGEN accesses are implicitly restrict, code that relied on these barriers for ordering can read or write stale data. Use the mem_fence intrinsic or a function call boundary to enforce memory ordering.

Toolchain Components#

Ordinarily, users do not need to invoke toolchain binaries directly — the PVA SDK build scripts handle compilation and linking automatically. However, the individual tools are documented here for users who need to invoke them manually or integrate them into custom build systems.

All toolchain binaries are installed to /opt/nvidia/pva-sdk-2.10/tools/nvvpu/bin/. All tools require --target=nvvpu-none-elf and a -mcpu flag to select the PVA generation:

  • -mcpu=orin — Target GEN2 (Orin) VPU architecture

  • -mcpu=thor — Target GEN3 (Thor) VPU architecture

clang++ — Compiler

Compiles C/C++ source files and .s assembly files to VPU object code.

clang++ --target=nvvpu-none-elf -mcpu=orin -nostdlib -c kernel.c -o kernel.o
lld — Linker

Links VPU object files into executables. Typically invoked through clang++ as linker driver rather than directly.

clang++ --target=nvvpu-none-elf -mcpu=orin -nostdlib -Wl,-T,cupva_orin.ld kernel.o -o kernel.elf
llvm-ar — Archiver

Creates static libraries (.a archives) from VPU object files.

llvm-ar rc libkernels.a kernel1.o kernel2.o
llvm-objdump — Disassembler

Disassembles VPU object files and ELFs, and displays section headers, symbols, and relocations. Automatically invoked for all build artifacts when building with PVA_DISASSEMBLE=ON.

llvm-objdump -d kernel.elf         # Disassemble code sections
llvm-objdump -t kernel.o           # Display symbol table
llvm-objdump -h kernel.elf         # Display section headers
llvm-readelf — ELF Inspector

Displays detailed ELF information including sections, segments, symbols, and notes.

llvm-readelf -a kernel.elf         # Display all ELF information
llvm-readelf -S kernel.elf         # Display section headers
llvm-readelf -s kernel.elf         # Display symbol table
llvm-strip — Binary Stripping

Removes debug information and symbols from VPU ELF files to reduce binary size. Automatically applied to .elf.flipped binaries during the build.

llvm-strip kernel.elf               # Strip all symbols and debug info
llvm-strip --strip-debug kernel.elf  # Strip only debug info
lldb / lldb-server — Debugger

lldb provides interactive debugging of VPU programs. lldb-server supports remote debugging of VPU code running on target hardware. Refer to VPU Debugging to get started.

Runtime Libraries#

The toolchain provides runtime support libraries that are linked automatically when building with PVA SDK build scripts. These may need to be linked/included manually if not using PVA SDK build scripts.

  • libclang_rt.builtins.a — Clang builtin functions for the VPU target.

  • libc++ headers — A subset of C++ standard library headers providing type support (<limits>, <type_traits>, <cstdint>, etc.).