Verify Correctness of the Generated Code
After you generate code, GPU Coder™ provides you multiple options to inspect the source code and test the correctness of the generated code.
The code generation report provides an interactive interface for inspecting the generated CUDA® source files, generated data types, and other code insights. For more information, see Code Generation Reports.
You can verify generated MEX functions using the GPU Coder app or the command-line interface.
With the MATLAB® Coder™ Support Package for NVIDIA® Jetson and NVIDIA DRIVE Platforms, you can use the processor-in-the-loop (PIL) execution to check the numerical behavior of the CUDA code that you generate from MATLAB functions. For more information, see Processor-in-the-Loop Execution from Command Line and Processor-In-The-Loop Execution with the GPU Coder App.
If you have Embedded Coder®, you can verify the numerical behavior of the generated CUDA code by using software-in-the-loop (SIL) execution.
Note
GPU Coder does not support collecting code coverage metrics during software-in-the-loop (SIL) and processor-in-the-loop (PIL) simulations.
Verify MEX Functions in the GPU Coder App
In the GPU Coder app, you can verify that a generated MEX function has the same functionality as the original MATLAB entry-point function. MEX verification allows you to check for errors during code generation and to compare the output of the MEX function with the entry-point function. MEX verification also checks for run-time issues in generated C/C++ MEX functions. To check for run-time issues during MEX verification, in the toolstrip, set the Language to C or C++ before doing MEX verification.
Provide a test file that generates test vectors for the function under test and then calls the original MATLAB entry-point function. The test file can be a MATLAB function or script and must be in the same folder as the original entry-point function.
In the GPU Coder toolstrip, click Run Generated MEX > Select MATLAB File to Run.
Select the test file that runs the entry-point function. The app runs the test file and replaces any calls to the MATLAB function with calls to the generated MEX function.
Compare the results of running the original MATLAB function with the results of the generated CUDA MEX function.
Verify MEX Functions at the Command Line
You can verify the generated CUDA MEX file at the command line by using the coder.runTest
function. The
coder.runTest
function runs the test file by replacing calls
to the original MATLAB function with calls to the MEX function. For example, to test
myfunction
function with myfunction_test
test file, enter the following code in the MATLAB Command
Window.
coder.runTest('myfunction_test','myfunction')
Compare the results with the results of running the original MATLAB function. If errors occur during the run, call stack information is available for debugging. Alternatively, you can use codegen
with the -test
option.
codegen myfunction -test'myfunction_test'
The test file can be a MATLAB function, script, or class-based unit test.
Code Verification Through Software-in-the-Loop Execution
GPU Coder supports software-in-the-loop (SIL) execution, which enables you to verify source code and compiled object code. During SIL execution through a MATLAB SIL interface, the software compiles the code and uses the test vectors that you provide to run the library code on your development computer. You can reuse test vectors developed for your MATLAB functions to verify the numerical behavior of library code.
Note
On a Microsoft® Windows® system, the Windows Firewall can potentially block a SIL execution. Change the Windows Firewall settings to allow access.
When using SIL execution, make sure that the
Benchmarking
option in GPU Coder settings isfalse
. Executing SIL with benchmarking results in compilation errors.
SIL Execution with the GPU Coder App
Follow these steps to run SIL execution in the GPU Coder app.
In the GPU Coder app, in the GPU Coder tab, set Output Type to Static Library or Dynamic Library.
To start SIL execution, click Run Generated Code > Select MATLAB File to Run. Specify the test file that calls the original MATLAB functions.
The GPU Coder app starts SIL execution. The app:
Generates a standalone library in
codegen\lib\myfunction
.Generates SIL interface code in
codegen\lib\myfunction\sil
.Runs the test file and replaces calls to the MATLAB function with calls to the generated code in the library.
Displays messages from the SIL execution in the Output section of the GPU Coder panel.
Verify that the results from the SIL execution match the results from the original MATLAB functions.
To terminate the SIL execution process, in the toolstrip, click Stop. Alternatively, in the MATLAB Command Window, click the link that follows
To terminate execution
.
SIL Execution from Command Line
To set up and start a SIL execution from the command line, you create a GPU Coder configuration object for library code generation, enable config_obj.VerificationMode = 'SIL'
, use codegen
function to generate the library code and the SIL interface, and use coder.runTest
function to run the test file for your original MATLAB function. The following is a build script that automates the series of commands to perform SIL execution.
%% Create configuration object for static library. config = coder.gpuConfig('lib'); config.GenerateReport = true; config.VerificationMode = 'SIL'; %% Define argument types for entry-point 'mandelbrot_count'. ARGS = cell(1,1); ARGS{1} = cell(3,1); ARGS{1}{1} = coder.typeof(0); ARGS{1}{2} = coder.typeof(0,[1000 1000]); ARGS{1}{3} = coder.typeof(0,[1000 1000]); %% Invoke GPU Coder. codegen -config config myfunction -args ARGS{1} %% Run the test file with the sil interface coder.runTest('myfunction_test', ['myfunction_sil.' mexext]); %% Terminate SIL execution clear myfunction_sil;
Numerical Differences Between CPU and GPU
Because of architectural differences between the CPU and GPU, numerical verification does not
always match. This scenario is especially true when
using single
data type in your MATLAB code and performing accumulation operations on these
single
data type values. However, there are cases like the
Mandelbrot example where even double
data types cause numerical
errors. One reason for this mismatch is that the GPU floating-point units use fused
Floating-Point Multiply-Add (FMAD) instructions while the CPU does not use these
instructions. It is also important to note that the CUDA compiler performs these instruction-level optimizations by default
impacting the accuracy of the computed results. For example, the CUDA compiler fuses floating-point multiply and add instructions into a
single instruction. This Floating-point Multiply-Add (FMAD) operation executes twice
as fast compared to two single instructions but results in the loss of numerical
accuracy. You can achieve tighter control over these optimizations by using
intrinsic functions and compiler flags. To set compiler flags, see coder.gpuConfig
. To integrate CUDA intrinsics, see Call Custom CUDA Device Function from the Generated Code.