Main Content

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 is false. 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.

  1. To open the GPU Coder app, on the MATLAB toolstrip Apps tab, under Code Generation, click the app icon.

  2. 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 .

  3. In the Generate dialog box:

    • Set Build type to Static Library or Dynamic Library.

    • Clear the Generate code only check box.

    • You can leave the other settings to their default values.

  4. To generate the CUDA code, click Generate. Click Verify Code.

  5. In the command field, specify the test file (for example, myfunction_test.m) that calls the original MATLAB functions (for example, myfunction).

  6. 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.

  7. Verify that the results from the SIL execution match the results from the original MATLAB functions.

  8. 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.

See Also

Apps

Functions

Objects

Related Topics