Main Content

Generate Code by Using the GPU Coder App

This example shows how to generate CUDA® code from a MATLAB® function by using GPU Coder™. The entry-point function is a MATLAB implementation of the Mandelbrot set algorithm. This example uses the GPU Coder app to check for run-time issues in the generated code and to generate a MEX function that can run on a GPU. For an example that shows how to generate code programmatically, see Generate Code Using the Command Line Interface.

Verify the GPU Environment

This example generates a CUDA MEX function and requires a CUDA-enabled NVIDIA® GPU and compatible driver. For more information, see Setting Up the Prerequisite Products.

To verify that the compilers and libraries necessary to run this example are set up correctly, use the coder.checkGpuInstall function:

envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
coder.checkGpuInstall(envCfg);
Compatible GPU           : PASSED 
CUDA Environment         : PASSED 
	Runtime   : PASSED 
	cuFFT     : PASSED 
	cuSOLVER  : PASSED 
	cuBLAS    : PASSED 
Host Compiler            : PASSED 
Basic Code Generation    : PASSED 

The output above is an example of a call to coder.checkGpuInstall. The output may be different when you run this code.

Mandelbrot Entry-Point Function

The Mandelbrot set is the region in the complex plane that consists of the values z0 for which the trajectories defined by

zk+1=zk2+z0,k=0,1,...

remain bounded at k. The figure shows the overall geometry of the Mandelbrot set. This view does not have the resolution to show the detailed structure of the fringe outside the boundary of the set.

The Mandelbrot set.

The mandelbrot_count.m entry-point function contains a vectorized implementation of the Mandelbrot set based on the code provided in Experiments with MATLAB by Cleve Moler.

type mandelbrot_count.m
function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen

% Copyright 2016-2024 The MathWorks, Inc. 

z0 = complex(xGrid, yGrid);
count = ones(size(z0));

% Map computation to GPU.
coder.gpu.kernelfun;

z = z0;
for n = 0:maxIterations
    z = z.*z + z0;
    inside = abs(z)<=2;
    count = count + inside;
end
count = log(count);

The entry-point function contains the coder.gpu.kernelfun pragma to map the computation inside the function to a CUDA kernel. The %#codegen directive inside mandelbrot_count causes MATLAB to check the function for warnings and errors related to code generation.

Test the Functionality of the Entry-Point Function

The mandelbrot_test.m script generates a 1000-by-1000 grid of real and imaginary parts between the limits xlim and ylim. It calls mandelbrot_count with this grid and plots the resulting Mandelbrot set.

type mandelbrot_test.m
% Copyright 2024 The MathWorks, Inc.

maxIterations = 500;
gridSize = 1000;
xlim = [-0.748766713922161,-0.748766707771757];
ylim = [0.123640844894862,0.123640851045266];

x = linspace(xlim(1),xlim(2),gridSize);

y = linspace(ylim(1),ylim(2),gridSize);

[xGrid,yGrid] = meshgrid(x,y); 

%% Mandelbrot computation in MATLAB

count = mandelbrot_count(maxIterations,xGrid,yGrid);

%% Show

figure(1)
imagesc(x,y,count);
colormap([jet();flipud(jet());0 0 0]);
axis off
title('Mandelbrot set with MATLAB');

Run the mandelbrot_test script to plot the Mandelbrot set in the boundaries of xlim and ylim.

mandelbrot_test

Generate Code with the GPU Coder App

In the MATLAB Toolstrip, in the Apps tab, click GPU Coder to open the app. Alternatively, open the app by entering gpucoder at the MATLAB command line:

gpucoder

The app opens the Select tab. Enter the name of the primary function, mandelbrot_count. The app creates a project with the name mandelbrot_count.prj in the current folder.

The GPU Coder App Select screen with mandelbrot_count selected.

When you click Next, the app runs the code generation readiness tool. The tool screens the MATLAB code for features and functions that do not support code generation. The app then opens the Review Code Generation Readiness page if it detects issues. In this example, the GPU Coder App does not detect code generation readiness issues. Click Next to proceed to the Define Input Types step.

Define Input Types

GPU Coder must determine the data types of the variables in your MATLAB code before it generates code. Therefore, you must specify the data types of the input variables for your entry-point functions on the Define Input Types page. You can specify the input data types by providing a file that calls the entry-point functions in your project or by entering the input data types manually in the app.

In this example, mandelbrot_test calls the entry-point function mandelbrot_count. Enter the test file mandelbrot_test and click Autodefine Input Types.

The Define Input Types screen. The app defines the input types based on the mandelbrot_test file.

Click Next to go to the Check for Run-Time Issues page.

Check for Run-Time Issues

The Check for Run-Time Issues page generates a MEX file from your entry-point functions, runs the MEX function, and reports issues. This step is optional. However, you can use this step to detect and fix defects that are harder to diagnose in the generated GPU code.

Click the arrow next to Check for Issues to open a drop-down menu. In this menu, you can specify a test file that calls the entry-point function. Select the mandelbrot_test.m file that you used to define the input types.

You can check for issues in the generated code on the CPU or the GPU:

  • When you select the CPU button, GPU Coder generates code and a MEX file to run on the CPU.

  • When you select the GPU button, GPU Coder generates CUDA code and a MEX file to run on the GPU.

There may be MATLAB constructs in your code that cause GPU Coder to detect issues on the CPU but not on the GPU. Check for run-time issues on the CPU and then on the GPU before proceeding to the next step.

Select GPU and click the Check for Issues button. The GPU Coder app runs mandelbrot_test and replaces calls to mandelbrot_count with calls to the generated MEX function. In this example, GPU Coder does not detect run-time issues on the GPU.

The Check for Run-Time Issues page. The app reports that it detected no issues.

Generate a CUDA MEX Function

In the Generate Code page, you can choose how you want GPU Coder to build the generated code. For this example, set Build type to MEX.

The Generate Code step of the app before generating a MEX file.

Because of architectural differences between the CPU and GPU, numerical verification does not always match. In this example, the double data type causes numeric errors between the CPU and the GPU. One reason for this mismatch is that the GPU uses floating-point multiply-add (FMAD) instructions, and the CPU does not. For more information, see Numerical Differences Between CPU and GPU.

To turn off FMAD instructions, click the More Settings button. In the left pane, click GPU Code. In the Compiler Flags box, enter --fmad=false.

The GPU Code tab. The Compiler Flags option contains the flag --fmad=false.

Close the settings window. Click Generate to generate the MEX file. By default, GPU Coder generates mandelbrot_count_mex in the current directory.

To compare the generated MEX function with the original MATLAB function, see Verify Correctness of the Generated Code.

See Also

Apps

Functions

Objects

Related Topics