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 |
Review code that depends on scheduling annotations; see Chess C/C++ code extensions. |
Scheduling barriers |
|
Use the |
Linker configuration |
NVVPU uses |
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 |
|---|---|---|
|
Same as Chess |
Memory type (DMb, DRAM, RAM_Ab, etc.), alignment, and segment are fully respected. Generates appropriate ELF section placement. |
|
Same as Chess |
Custom segment names are applied. Used in conjunction with |
|
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. |
|
Same as Chess |
Maps directly to standard C++ |
|
Same as Chess |
Used to indicate a variable is used and should not be eliminated. |
|
Same intent |
Converted to clang attribute may_alias. |
|
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.).