Main Content

Getting Started with the MATLAB Coder Support Package for NVIDIA Jetson and NVIDIA DRIVE Platforms

This example shows how to use the MATLAB® Coder™ Support Package for NVIDIA Jetson™ and NVIDIA DRIVE® Platforms with embedded boards from NVIDIA®. The example uses a simple vector addition algorithm to illustrate:

  • Connection to the embedded board from the MATLAB® environment.

  • Perform basic operations such as file transfer to and from MATLAB and executing Linux® shell commands on the board.

  • Generate C++ executable from a MATLAB function and run the executable on the ARM® CPU in the board.

  • Generate CUDA® executable from a MATLAB function and run the executable on the NVIDIA GPU in the board.

nvidiaHSPImage.jpg

Prerequisites

Target Board Requirements

  • NVIDIA DRIVE PX2 or Jetson embedded platform.

  • Ethernet crossover cable to connect the target board and host PC (if you cannot connect the target board to a local network).

  • NVIDIA CUDA toolkit and libraries installed on the board.

  • Environment variables on the target for the compilers and libraries. For more information, see Install and Setup Prerequisites for NVIDIA Boards.

Development Host Requirements

Connect to NVIDIA Hardware

The support package uses an SSH connection over TCP/IP to execute commands while building and running the generated code on the Jetson or DRIVE platforms. Connect the target platform to the same network as the host computer or use an Ethernet crossover cable to connect the board directly to the host computer. For information on how to set up and configure your board, see NVIDIA documentation.

To communicate with the NVIDIA hardware, create a live hardware connection object by using the drive or jetson function. When connecting to the target board for the first time,you must provide the host name or IP address, user name, and password of the target board. On subsequent connections, you do not need to supply the address, user name, and password. The hardware object reuses these settings from the most recent successful connection to an NVIDIA board.

By default, this example reuses the settings from the most recent successful connection to a NVIDIA Jetson board. To connect to a different board, change the deviceAddress, userName, password, and boardName in the following lines of code:

deviceAddress = ''; 
userName = 'ubuntu';
password = 'ubuntu';
boardName = "jetson";

During the hardware live object creation, the support package performs hardware and software checks, installs MATLAB IO server on the target board, and gathers information on peripheral devices connected to the target. This information is displayed in the Command Window. In case of a connection failure, a diagnostics error message is reported at the MATLAB command line. If the connection has failed, the most likely cause is incorrect IP address or host name.

if (boardName == "jetson")
    if isempty(deviceAddress)
        hwobj = jetson();
    else
        hwobj = jetson(deviceAddress,userName,password);
    end
else
    if isempty(deviceAddress)
        hwobj = drive();
    else
        hwobj = drive(deviceAddress,userName,password);
    end
end
Checking for CUDA availability on the Target...
Checking for 'nvcc' in the target system path...
Checking for cuDNN library availability on the Target...
Checking for TensorRT library availability on the Target...
Checking for prerequisite libraries is complete.
Gathering hardware details...
Checking for third-party library availability on the Target...
Gathering hardware details is complete.
 Board name              : NVIDIA Jetson AGX Xavier Developer Kit
 CUDA Version            : 11.4
 cuDNN Version           : 8.4
 TensorRT Version        : 8.4
 GStreamer Version       : 1.16.3
 V4L2 Version            : 1.18.0-2build1
 SDL Version             : 1.2
 OpenCV Version          : 4.5.4
 Available Webcams       : Logitech Webcam C925e
 Available GPUs          : Xavier
 Available Digital Pins  : 7  11  12  13  15  16  18  19  21  22  23  24  26  29  31  32  33  35  36  37  38  40

Run Linux Commands on NVIDIA Hardware

When a successful connection to the board is established, you can use the system method of the board object to execute various Linux shell commands on the NVIDIA hardware from MATLAB. For example, to list the contents of the home folder on the target board, use the command:

system(hwobj,'ls -al ~');

The hardware object provides basic file manipulation capabilities. To transfer files from the host to the target use the putFile() method of the live hardware object. For example, to transfer the gsTestFile.txt file in the current folder to the remoteBuildDir on the target board, use the command:

putFile(hwobj,'gsTestFile.txt','~/remoteBuildDir');

To copy a file from the target board to the host computer, use the getFile() method of the hardware object. For example,

getFile(hwobj,'~/remoteBuildDir/gsTestFile.txt','.');

Generate C++ code for the ARM CPU Using MATLAB Coder

This example uses gsAdd.m, a simple vector addition, as the entry-point function for code generation.

type gsAdd
function out = gsAdd(inp1,inp2) %#codegen

out = inp1 + inp2;
end

To generate an executable that you can deploy on to an NVIDIA target, create a code configuration object for generating an executable.

cfg = coder.config('exe');
cfg.TargetLang = 'C++';

When there are multiple live connection objects for different targets, the code generator performs a remote build on the target board for which a recent live object was created. To choose a hardware board for performing a remote build, use the setupCodegenContext() method of the respective live hardware object. If only one live connection object was created, you do not need to call this method.

hwobj.setupCodegenContext;

To create a configuration object for the DRIVE or Jetson platform and assign it to the Hardware property of the code configuration object cfg, use the coder.hardware function. Use 'NVIDIA Jetson' for the Jetson boards and 'NVIDIA Drive' for the DRIVE board.

if (boardName == "jetson")
    cfg.Hardware = coder.hardware('NVIDIA Jetson');
else
    cfg.Hardware = coder.hardware('NVIDIA Drive');
end

To specify the folder for performing remote build process on the target board, use the BuildDir property. If the specified build folder does not exist on the target board, then the software creates a folder with the given name. If no value is assigned to cfg.Hardware.BuildDir, the remote build process occurs in the last specified build folder. If there is no stored build folder value, the build process takes place in the home folder.

cfg.Hardware.BuildDir = '~/remoteBuildDir';

The custom gsMain.cpp file is a wrapper that calls the entry point function in the generated code. This main file passes a vector containing the first 100 natural numbers to the entry-point function. The main file writes the results to the gsAdd.bin binary file.

cfg.CustomSource  = fullfile('gsMain.cpp');

To generate C++ code, use the codegen function and pass the code configuration and the size of the inputs for and gsAdd.m entry-point function. After the code generation takes place on the host, the generated files are copied over and built on the target board.

codegen('-config ',cfg,'gsAdd','-args',{1:100,1:100});
Code generation successful.

Run Executable for the ARM CPU on Target Board

To run the executable on the target hardware, use the runApplication() method of the hardware object.

pid = runApplication(hwobj,'gsAdd');
### Launching the executable on the target...
Executable launched successfully with process ID 826182.
Displaying the simple runtime log for the executable...

Note: For the complete log, run the following command in the MATLAB command window:
system(hwobj,'cat /home/ubuntu/remoteBuildDir/MATLAB_ws/R2023b/home/lnarasim/Documents/MATLAB/ExampleManager/lnarasim.Bdoc23b.j2336540/nvidia-ex79422933/gsAdd.log')

Alternatively, to run the executable, use the runExecutable() method of the hardware object.

exe = [hwobj.workspaceDir '/gsAdd.elf']; 
pid = runExecutable(hwobj,exe);

Verify Result from Target Board

Copy the output bin file myAdd.bin to the MATLAB environment on the host and compare the computed results to those from MATLAB. The property workspaceDir contains the path to the codegen folder on the target board.

pause(0.3); % To ensure that the executable completed the execution.
getFile(hwobj,[hwobj.workspaceDir '/gsAdd.bin']);

Simulation result from the MATLAB:

simOut = gsAdd(0:99,0:99);

Read the copied result binary file from target in MATLAB:

fId  = fopen('gsAdd.bin','r'); 
tOut = fread(fId,'double');

Find the difference between the MATLAB simulation output and the output from target board.

diff = simOut - tOut';

Display the maximum deviation between the simulation output and the output from target board.

fprintf(['Maximum deviation between MATLAB Simulation output' ...
    ' and the output from the CPU on Target is: %f\n'], max(diff(:)));
Maximum deviation between MATLAB Simulation output and the output from the CPU on Target is: 0.000000

Generate CUDA Code for the Target Board Using GPU Coder

Verify GPU Environment on Target Board

To verify that the compilers and libraries necessary for running this example are set up correctly, use the coder.checkGpuInstall function.

if (boardName == "jetson")
    envCfg = coder.gpuEnvConfig('jetson'); 
else
    envCfg = coder.gpuEnvConfig('drive'); 
end
envCfg.BasicCodegen = 1; 
envCfg.Quiet = 1;
envCfg.HardwareObject = hwobj; 
coder.checkGpuInstall(envCfg);

Generate CUDA Executable

To generate a CUDA executable that you can deploy on to an NVIDIA target, create a GPU code configuration object for generating an executable.

cfg = coder.gpuConfig('exe');
if (boardName == "jetson")
    cfg.Hardware = coder.hardware('NVIDIA Jetson');
else
    cfg.Hardware = coder.hardware('NVIDIA Drive');
end
cfg.Hardware.BuildDir = '~/remoteBuildDir';
cfg.CustomSource  = fullfile('gsMain.cu');

Certain NVIDIA platforms such as DRIVE PX2 contain multiple GPUs. On such platforms, use the SelectCudaDevice property in the GPU configuration object to select a specific GPU.

cfg.GpuConfig.SelectCudaDevice = 0;
codegen('-config ',cfg,'gsAdd','-args',{1:100,1:100});
Code generation successful.

Run Executable for the GPU on Target Board

To run the executable on the target hardware, use the runApplication() method of the hardware object.

pid = runApplication(hwobj,'gsAdd');
### Launching the executable on the target...
Executable launched successfully with process ID 826567.
Displaying the simple runtime log for the executable...

Note: For the complete log, run the following command in the MATLAB command window:
system(hwobj,'cat /home/ubuntu/remoteBuildDir/MATLAB_ws/R2023b/home/lnarasim/Documents/MATLAB/ExampleManager/lnarasim.Bdoc23b.j2336540/nvidia-ex79422933/gsAdd.log')

Verify Result from Target Board

Copy the output bin file myAdd.bin to the MATLAB environment on the host and compare the computed results to those from MATLAB. The property workspaceDir contains the path to the codegen folder on the target board.

pause(0.3); % To ensure that the executable completed the execution.
getFile(hwobj,[hwobj.workspaceDir '/gsAdd.bin']);

Simulation result from the MATLAB:

simOut = gsAdd(0:99,0:99);

Read the copied result binary file from target in MATLAB:

fId  = fopen('gsAdd.bin','r'); 
tOut = fread(fId,'double');

Find the difference between the MATLAB simulation output and the output from target board.

diff = simOut - tOut';

Display the maximum deviation between the simulation output and the output from target board.

fprintf(['Maximum deviation between MATLAB Simulation output' ...
    ' and the output from the GPU on Target is: %f\n'], max(diff(:)));
Maximum deviation between MATLAB Simulation output and the output from the GPU on Target is: 0.000000

See Also

Objects

Related Topics