This example shows how to use the GPU Coder™ Support Package for NVIDIA GPUs and connect to NVIDIA® DRIVE™ and Jetson hardware platforms, perform basic operations, generate CUDA® executable from a MATLAB® function, and run the executable on the hardware. This example uses a simple vector addition.
Target Board Requirements
NVIDIA DRIVE PX2 or Jetson TX1/TX2 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 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 (GPU Coder Support Package for NVIDIA GPUs).
Development Host Requirements
GPU Coder for CUDA code generation. For a tutorial, see Get Started with GPU Coder.
GPU Coder Interface for Deep Learning Libraries support package. To install this support package, use the MATLAB®
NVIDIA CUDA toolkit on the host.
The following line of code creates a folder in your current working folder on the host and copies all the relevant files into this folder. If you cannot generate files in this folder, before running this command, change your current working folder.
The GPU Coder Support Package for NVIDIA GPUs uses an SSH connection over TCP/IP to execute commands while building and running the generated CUDA code on the DRIVE or Jetson 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 (GPU Coder Support Package for NVIDIA GPUs) or
jetson (GPU Coder Support Package for NVIDIA GPUs) function. You must know the host name or IP address, user name, and password of the target board to create a live hardware connection object. For example, when connecting to the target board for the first time, create a live object for Jetson hardware by using the command:
hwobj = jetson('jetson-tx2-name','ubuntu','ubuntu');
During the hardware live object creation, the support package performs hardware and software checks, IO server installation, and gathers peripheral information on target. This information is displayed in the Command Window.
Similarly, to create live object for DRIVE hardware, use the command:
hwobj = drive('drive-px2-name','ubuntu','ubuntu');
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.
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
test.txt file in the current folder to the
remoteBuildDir on the target board, use the command:
To copy a file from the target board to the host computer, use the
getFile() method of the hardware object. For example,
To verify that the compilers and libraries necessary for running this example are set up correctly, use the
envCfg = coder.gpuEnvConfig('jetson'); % Use 'drive' for NVIDIA DRIVE hardware envCfg.BasicCodegen = 1; envCfg.Quiet = 1; envCfg.HardwareObject = hwobj; coder.checkGpuInstall(envCfg);
This example uses
myAdd.m, a simple vector addition, as the entry-point function for code generation. 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');
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.
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 TX1 or TX2 boards and
'NVIDIA Drive' for the DRIVE board. cfg.Hardware = coder.hardware('NVIDIA Jetson');
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';
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;
main.cu 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
myAdd.bin binary file.
cfg.CustomSource = fullfile('main.cu');
To generate CUDA code, use the
codegen function and pass the GPU code configuration and the size of the inputs for and
myAdd.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.
To run the executable on the target hardware, use the
runApplication() method of the hardware object.
pid = runApplication(hwobj,'myAdd');
Alternatively, to run the executable, use the
runExecutable() method of the hardware object.
exe = [hwobj.workspaceDir '/myAdd.elf']; pid = runExecutable(hwobj,exe);
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 '/myAdd.bin']);
Simulation result from the MATLAB:
simOut = myAdd(0:99,0:99);
Read the copied result binary file from target in MATLAB:
fId = fopen('myAdd.bin','r'); tOut = fread(fId,'double');
Find the difference between the MATLAB simulation output and GPU coder output from target board.
diff = simOut - tOut';
Display the maximum deviation between the simulation output and GPU coder output from target board.
fprintf('Maximum deviation between MATLAB Simulation output and GPU coder output on Target is: %f\n', max(diff(:)));
To remove the example files and return to the original folder, call the