Using ASIP Programmer#
ASIP Programmer is an optional retargetable toolchain for building VPU code. When installed, PVA SDK build
scripts prefer it unless PVA_USE_NVVPU=ON forces the core NVVPU toolchain. Access and installation are
described in Installing ASIP Programmer.
ChessDE Debugging#
The following pages describe using ChessDE, the debugging environment from ASIP Programmer, to debug applications.
Chess linker and BCF files#
The Chess linker, bridge, uses a BCF file to control linking and memory layout for VPU ELFs. The SDK
provides a default BCF, which can be overridden with the BCF argument of pva_device when code layout
must be tuned. A custom BCF should include cupva_vpu.bcf before adding its own directives. The following
defines control the default layout; sizes are rounded up to 64-byte boundaries:
STACK_SIZEcontrols the stack size and defaults to0x1000.GLOBAL_SIZEcontrols the region for global and static variables that are not assigned to a specific bank, and defaults to0x800.CUPVA_NOMAP_MAINprevents the default placement ofCUPVA_MAINat the start of the program, allowing the application to place it later.
Functions can be placed with _next directives. Function names are mangled by default:
#define STACK_SIZE 0x800
#include <cupva_vpu.bcf>
_symbol some_mangled_function_name _next
_symbol some_other_mangled_function_name _next
The compiler, archiver, and linker can also be invoked directly as chesscc, ear, and bridge.
They require the VPU models installed under tools/vpu_sdks in the PVA SDK installation. Refer to the
ASIP Programmer manual for their complete command-line interfaces.
Chess C/C++ frontends#
ASIP Programmer’s compiler is named Chess. Chess supports two different frontends:
The chess-noodle C/C++ front-end. Noodle supports the C language and limited C++ features, such as references, function and operator overloading.
The chess-clang front-end is a newer option based on clang. It has better support for C++ features, in particular template metaprogramming.
Starting with PVA SDK 2.6, we have deprecated support for Noodle. PVA SDK now builds using chess-clang by default. This can be overridden with the build system flag USE_NOODLE, however note that:
cuPVA device runtime headers are not guaranteed to compile with chess-noodle; and,
There are restrictions on link-compatibility between objects built with chess-clang and chess-noodle. Refer chess documentation for details.
Chess-clang migration guide#
In general, code which compiles with chess-noodle will also compile with chess-clang. However there are some compatibility issues to be aware of when migrating code between these front-ends.
Function Inlining Control#
LLVM front-end supports automatic function inlining. It may decide not to inline a function with an inline specifier or to inline a non-inline function. There are three ways to influence the LLVM front end to control function inlining:
Force the user to inline a function using the
always_inlineannotation.[[gnu::always_inline]] inline int foo(int x) { ... }
Instruct the LLVM front-end to never inline a function using noinline annotation.
[[gnu::noinline]] int foo(int x) { ... }
Memory Fence#
LLVM front-end can perform more aggressive optimizations than the CHESS front-end, especially for those inline functions.
In some cases, the LLVM front-end may optimize away some VMEM store instructions; e.g., it fails to detect data dependencies between VMEM store and gpo_set instructions. To resolve such an issue, it is recommended to insert a chess_memory_fence before gpo_set instruction.
Prevent Breaking-Up Load and AGEN Restore Operations#
The LLVM front-end may perform aggressive optimization and break-up the load and AGEN restore operations apart, which causes compilation to fail. To resolve this issue, it is recommended to use the chess_protect_access annotation to protect the
accesses on AGEN variables.
chess_protect_access agen_A in1 = init_agen_A_from_cfg(agens.cfg[0]);
Vector Demotion Operation with Interleaving#
LLVM front-end doesn’t support passing .lo and .hi fields of a XARF (extended accumulator register file) double vector type by reference for some intrinsics; e.g., vdemote_i from VRF to XARF.
void vdemote_i(vintx src1, vintx src2, xvshortx &dst);
To workaround this issue, it is recommended to declare a single-vector XARF variable, and then pass it to the vdemote_i.
dvintx a;
xvshortx b;
vdemote_i(a.lo, a.hi, b);
Function Name Mangling#
The Chess linker (bridge) uses a BCF file to control linking and memory layout for VPU ELFs. VPU developers are allowed to create a custom BCF to control VPU code layout for performance reasons, which requires to use mangled function names.
The noodle front-end uses CHESS function name mangling scheme for function overloading support. By default, this name mangling scheme is enabled in PVA SDK. With LLVM front-end, the standard Itanium name mangling is used. To migrate an existing VPU kernel with a custom BCF file to LLVM front-end, a user needs to convert all mangled function names in the BCF to LLVM C++ symbol names. PVA SDK provides a Python script to facilitate this conversion process.
pvasdkConvertToLLVMBCF.py
Assuming that you have a cuPVA device target foo, which has an exiting noodle BCF file foo.bcf. The following steps are
required to use the script to convert a noodle BCF to a LLVM BCF.
Copy the
foo.bcftofoo_noodle.bcf.Remove/disable all the lines started with
_symbolinfoo.bcf.Build the foo target to generate foo lst file, which is needed in step 4.
Run
pvasdkConvertToLLVMBCF.pyto convert noodle symbol names to C++ symbol names.pvasdkConvertToLLVMBCF.py -i foo_noodle.bcf -l <FOO_LST_FILE> -o foo.bcf
Rebuild foo target with LLVM front-end and the converted
foo.bcf.
Note
Chess name mangling is a proprietary ASIP Programmer name mangling scheme. The pvasdkConvertToLLVMBCF.py script may not handle all the mangling cases.
Performance Optimization Tips#
The CHESS compiler provides chess_guard annotation for predicated execution. This annotation is currently not supported by LLVM front-end. The LLVM front-end does not try to map the operations inside the if-statements with chess_guard onto guarded instructions, instead it turns the if-statements into real branches using jumps, which can adversely impact performance, especially when the if-statements are inside a loop.
To resolve such an issue, the user can change the code to remove the if-statements if possible, and use the ternary operators instead.