My goal is to cross compile a machine learning inference framework for the Jetson Xavier NX device.
I will be cross compiling on an X86 device. In order to do so, I will first need to install the appropriate version of CUDA.
It looks like I need to install cuda-cross-aarch64 on my x86 device.
Based on the guide, I first need to run sudo dpkg -i cuda-repo-cross-<identifier>_all.deb
After navigating to that page, I make the initial selection âLinuxâ.
After that, I have two options, âx86_64â and âppc64leâ. Where is the arm64 / aarch64 version that I would require for the Jetson Xavier NX?
I see other answers suggesting I need to obtain the cuda toolchain from Jetpack, and then they refer you to this link: JetPack SDK | NVIDIA Developer
But what exactly do I do here. The only think I really see on that page is to download the JETSON XAVIER NX DEVELOPER KIT SD card image. How do I get the cuda-cross from an SD card image!?
I went ahead and used the SDK manager to install on the x86 host.
I now see that it installed to /usr/local/cuda/targets/aarch64-linux
However, when I try to cross compile using the aarch64 toolchain, I get the following errors when running CMake:
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/aarch64-linux-gnu-gcc
-- Check for working C compiler: /usr/bin/aarch64-linux-gnu-gcc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/aarch64-linux-gnu-g++
-- Check for working CXX compiler: /usr/bin/aarch64-linux-gnu-g++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CMAKE_CROSSCOMPILING TRUE
-- CMAKE_HOST_SYSTEM_PROCESSOR x86_64
-- CMAKE_SYSTEM_PROCESSOR aarch64
-- CMAKE_SYSTEM_NAME Linux
-- CMake version '3.17.0-rc1' using generator 'Ninja'
-- Looking for a CUDA compiler
-- Looking for a CUDA compiler - NOTFOUND
CMake Warning at CMakeLists.txt:94 (message):
CMAKE_CUDA_COMPILER guessed: /usr/local/cuda/bin/nvcc
-- The CUDA compiler identification is unknown
-- Check for working CUDA compiler: /usr/local/cuda/bin/nvcc
-- Check for working CUDA compiler: /usr/local/cuda/bin/nvcc - broken
CMake Error at /usr/local/share/cmake-3.17/Modules/CMakeTestCUDACompiler.cmake:46 (message):
The CUDA compiler
"/usr/local/cuda/bin/nvcc"
is not able to compile a simple test program.
How do I point CMake to the correct cuda cross compiler?
If I run a search under /usr/local/cuda and search for nvcc, the only one found is the one under /usr/local/cuda/bin/nvcc.
So where is the cross compiler I need?
Ok, looks like the issue had to do with the fact that the gcc on my system was gcc 9 and cuda 10.2 didnât support that version of gcc.
While on the topic, I have 1 more question.
When I cross compile code, I generally provide a toolchain file to cmake, and that toolchain file will contain something like this:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(TARGET_ABI "linux-gnu")
# specify the cross compiler
SET(CMAKE_C_COMPILER aarch64-${TARGET_ABI}-gcc)
SET(CMAKE_CXX_COMPILER aarch64-${TARGET_ABI}-g++)
# To build the tests, we need to set where the target environment containing
# the required library is. On Debian-like systems, this is
# /usr/aarch64-linux-gnu.
SET(CMAKE_FIND_ROOT_PATH "/usr/aarch64-${TARGET_ABI}")
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Set additional variables.
# If we don't set some of these, CMake will end up using the host version.
# We want the full path, however, so we can pass EXISTS and other checks in
# the our CMake code.
find_program(GCC_FULL_PATH aarch64-${TARGET_ABI}-gcc)
if (NOT GCC_FULL_PATH)
message(FATAL_ERROR "Cross-compiler aarch64-${TARGET_ABI}-gcc not found")
endif ()
get_filename_component(GCC_DIR ${GCC_FULL_PATH} PATH)
SET(CMAKE_LINKER ${GCC_DIR}/aarch64-${TARGET_ABI}-ld CACHE FILEPATH "linker")
SET(CMAKE_ASM_COMPILER ${GCC_DIR}/aarch64-${TARGET_ABI}-as CACHE FILEPATH "assembler")
SET(CMAKE_OBJCOPY ${GCC_DIR}/aarch64-${TARGET_ABI}-objcopy CACHE FILEPATH "objcopy")
SET(CMAKE_STRIP ${GCC_DIR}/aarch64-${TARGET_ABI}-strip CACHE FILEPATH "strip")
SET(CMAKE_CPP ${GCC_DIR}/aarch64-${TARGET_ABI}-cpp CACHE FILEPATH "cpp")
Itâs basically specifying which compiler to use (in this case,aarch64-linux-gnu-g++).
Now Iâm wondering, do I need to do something similar for cuda, as in, do I need to provide a cmake argument (in addition to the toolchain file above) to tell cmake that it should use the aarch64 cuda version for cross compiling? Or can it automatically detect that it needs to use that?
And if I do need to specify to cmake, what would that command line argument look like?
Thank you in advance for the help - this is my first time cross compiling a cuda application. I also appreciate the fast responses.
That still doesnât answer my question.
What Iâm asking is if I need to tell cmake somehow to use the aarch64 version of cuda. And if so, how do I do that.
sudo dpkg -i cuda-repo-cross-_all.deb
If you run SDK Manager and progress further steps, SDKM will install lots of contents both on your x86 host and the AGX Xavier. You can find cuda-repo-cross-xxx files at $HOME/Downloads/nvidia/sdkm_downloads/on your host side, if you do choose default configurations. libcudnn8-xxx for Jetson AGX Xaviver would be there as well.
But, libucdnn8 for x86, your host pc, it should be downloaded and installed from [here].
toolchain.
SDK manager will install proper toolchain during the installation on your host PC.
You can find it at /usr/bin/aarch64-linux-gnu-xxx
If NOT, you can install it by manual, linaro toolchain directly or apt-get sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
If cmake cannot find cross-toolchain and nvcc, check your PATH variable is valid.
SDK manger would install the proper toolchain at /usr/bin.
Then find the directory is in the PATH variable or not.
If not, add it shortly and test it works as expected.