Main Content

Processor-in-the-Loop Execution on NVIDIA Targets Using GPU Coder

This example shows how the MATLAB® Coder™ Support Package for NVIDIA® Jetson™ and NVIDIA DRIVE™ Platforms enables the GPU Coder™ product to run PIL execution on NVIDIA DRIVE and Jetson hardware platforms. This example uses the GPU Code generation for fog rectification example from GPU Coder to demonstrate PIL execution. For more information, see Fog Rectification (GPU Coder).

Prerequisites

Target Board Requirements

  • NVIDIA Jetson or DRIVE embedded platform.

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

  • NVIDIA CUDA toolkit 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 TX2 Developer Kit
 CUDA Version            : 10.2
 cuDNN Version           : 8.2
 TensorRT Version        : 8.2
 GStreamer Version       : 1.14.5
 V4L2 Version            : 1.14.2-1
 SDL Version             : 1.2
 OpenCV Version          : 4.1.1
 Available Webcams       : Logitech Webcam C925e
 Available GPUs          : NVIDIA Tegra X2
 Available Digital Pins  : 7  11  12  13  15  16  18  19  21  22  23  24  29  31  32  33  35  36  37  38  40

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 (GPU Coder) 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 Code for PIL Execution on Target Board Using GPU Coder

To run PIL execution NVIDIA target, create a GPU code configuration object for 'lib' and set verification mode to 'PIL'.

cfg = coder.gpuConfig('lib');
cfg.VerificationMode = 'PIL';

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 enable code execution profiling, set CodeExecutionProfiling of the GPU Coder configuration object to true.

cfg.CodeExecutionProfiling = true;

Load sample foggy input image.

foggyImg = imread('foggyInput.png');

To generate CUDA code, use the codegen function and pass the GPU code configuration and the size of the inputs for fogRectification entry-point function. The code generator creates a MEX function named fogRectification_pil for PIL-based execution.

codegen('-config ',cfg,'fogRectification','-args',{foggyImg});
### Connectivity configuration for function 'fogRectification': 'NVIDIA Jetson'
PIL execution is using Port 17725.
PIL execution is using 30 Sec(s) for receive time-out.
Code generation successful: View report

Run PIL MEX function

To run the generated code on the target board and get the results into MATLAB, call the fogRectification_pil MEX function with required input.

defoggyImg_pil = fogRectification_pil(foggyImg);
### Starting application: 'codegen/lib/fogRectification/pil/fogRectification.elf'
    To terminate execution: clear fogRectification_pil
### Launching application fogRectification.elf...
    Execution profiling data is available for viewing. Open Simulation Data Inspector.
    Execution profiling report will be available after termination.
p1  = subplot(1, 2, 1);
p2 = subplot(1, 2, 2);
imshow(foggyImg, 'Parent', p1);
imshow(defoggyImg_pil, 'Parent', p2);
title(p1, 'Foggy Input Image');
title(p2, 'Defogged Output Image from Hardware');

Figure contains 2 axes objects. Axes object 1 with title Foggy Input Image contains an object of type image. Axes object 2 with title Defogged Output Image from Hardware contains an object of type image.

Verify Generated Code

To verify the numeric accuracy of the generated code, compare MATLAB results to those from the PIL execution.

defoggyImg_sim = fogRectification(foggyImg);
diffImg =  defoggyImg_sim - defoggyImg_pil;
fprintf('The maximum difference between the PIL output and simulation output is %f\n', max(diffImg(:)));
The maximum difference between the PIL output and simulation output is 0.000000

Profiling Results

After clearing the PIL MEX function, profiling results are available.

clear('fogRectification_pil');
Runtime log on Target:
[sudo] password for ubuntu: 
PIL execution terminated on target.
    Execution profiling report: coder.profile.show(getCoderExecutionProfile('fogRectification'))

Configure the report generator and open the profiling report. TimerTicksPerSecond holds the target hardware clock frequency.

executionProfile=getCoderExecutionProfile('fogRectification');
executionProfile.TimerTicksPerSecond = 2035 * 1e6;
report(executionProfile, ...
'Units', 'Seconds', ...
'ScaleFactor', '1e-03', ...
'NumericFormat', '%0.3f');