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.
Verify generated MEX functions in the GPU Coder app.
Verify generated MEX functions at the command line.
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, after you generate a MEX function, you can verify that it has the same functionality as the original MATLAB entry-point function. 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 but must be in the same folder as the original entry-point function.
On the Generate Code page of the GPU Coder app, click Verify Code.
Type or select the test file. For example,
myfunction_test
.To run the test file without replacing calls to the original MATLAB function with calls to the MEX function, select MATLAB code for the Run using option. Click Run MATLAB Code.
To run the test file, replacing calls to the original MATLAB function with calls to the MEX function, select Generated code for the Run using option. Click Run Generated Code.
Compare the results of running the original MATLAB function with the results of running 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
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 and using the test vectors that you provide, runs 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
The software-in-the-loop (SIL) execution is supported only for static and dynamic library output types. If you generated a MEX function, you must change the project settings to use Static Library
or Dynamic Library
for Build type and run Generate code again.
To open the GPU Coder app, on the MATLAB toolstrip Apps tab, under Code Generation, click the app icon.
To open your project, click , and then click
Open existing project
. Select the project,myproject.prj
. On the Generate Code page, click the Generate arrow .In the Generate dialog box:
Set Build type to
Static Library
orDynamic Library
.Clear the Generate code only check box.
You can leave the other settings to their default values.
To generate the CUDA code, click Generate. Click Verify Code.
In the command field, specify the test file (for example,
myfunction_test.m
) that calls the original MATLAB functions (for example,myfunction
).To start the SIL execution, click Run Generated Code. The GPU Coder app:
Generates a standalone library in
codegen\lib\myfunction
.Generates SIL interface code in
codegen\lib\myfunction\sil
.Runs the test file, replacing calls to the MATLAB function with calls to the generated code in the library.
Displays messages from the SIL execution in the Test Output tab.
Verify that the results from the SIL execution match the results from the original MATLAB functions.
To terminate the SIL execution process, click Stop SIL Verification. Alternatively, on the Test Output tab, 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.