How do I install the required CUDA in order to cross compile on an X86 device for the Jetson Xavier NX device

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.

I have been following the guide here: Installation Guide Linux :: CUDA Toolkit Documentation

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

Where do I download that deb file from?
I am targetting cuda10.2. Based on the guide, it says to download the deb file from here: https://developer.nvidia.com/cuda-10.2-download-archive

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!?

Use SDK manager instead of SD image.
SDK manager should be installed on the x86 host, and provides you what you want.

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?

Hi,

It’s recommended to validate the nvcc tool first?
If you install CUDA with JetPack4.5, the version should be v10.2.

/usr/loca/cuda-10.2/bin/nvcc --version

If nvcc works well, you can setup the CUDA path to cmake like below:

$ cmake -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 ..

Thanks.

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.

Sorry I gave you confusion.
I thought that toolchain is in the JetPack so far.

Please find this toolchain to build what you want:
linaro toolchain:

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.

Additionally, I wasn’t able to find the cudnn8 installation.
The SDK manager mentioned that it would be installed as well.

Any ideas where it could be / why it was not installed?

@crystal.maung2
I would answer as much as I know.

  1. 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].

  2. CUDA toolkit for x86:
    CUDA Toolkit 10.2 Download | NVIDIA Developer

  3. 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.

1 Like

Thank you, very helpful!

so how to tell cmake to use the aarch64 version?

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.

$ export PATH=$PATH:/usr/bin
$ aarch64-linux-gnu-gcc -v

thanks a lot