Main Content

Relocate Generated Code to Another Development Environment

If you need to relocate the generated code files to another development environment, such as a system or an integrated development environment (IDE) that does not include MATLAB®, you can use the packNGo function at the command line or the GPU Coder™ app. The files are packaged in a compressed file that you can relocate and unpack using a standard zip utility.

Because the code generated by using GPU Coder relies on third-party compilers, libraries to build and run the executables, the development environment that you are relocating to must also satisfy these requirements. For more information, see Installing Prerequisite Products and Setting Up the Prerequisite Products.

Note

GPU Coder requires that the 'minimalHeaders' option of the packNGo command is set to false. This setting instructs the software to include all the header files found on the include path in the zip file (rather than the minimal header files required to build the code). For example, packNGo(buildInfo,'minimalHeaders',false).

Package Generated Code Using GPU Coder

This example shows how to package generated code into a zip file for relocation using the GPU Coder app. The example uses a Sobel edge detection application to demonstrate this concept. By default, GPU Coder creates the zip file in the current working folder.

Prerequisites

Sobel Edge Detection Entry-Point Function

In the Sobel edge detection algorithm, a 2-D spatial gradient operation on a grayscale image is performed. This operation emphasizes the high spatial frequency regions which corresponds to edges.

type sobelEdge.m
function [ magnitude ] = sobelEdge( Image )
%#codegen

%   Copyright 2017-2021 The MathWorks, Inc.


maskX = single([-1 0 1 ; -2 0 2; -1 0 1]);
maskY = single([-1 -2 -1 ; 0 0 0 ; 1 2 1]);

coder.gpu.kernelfun();



resX = conv2(Image, maskX, 'same');
resY = conv2(Image, maskY, 'same');

magnitude = sqrt(resX.^2 + resY.^2);
thresh = magnitude < 0.4;
magnitude(thresh) = 0;

end

The Sobel edge algorithm computes the horizontal gradient (resX) and the vertical gradient (resY) of the input image by using two orthogonal filter kernels (maskX and maskY). After the filtering operation, the algorithm computes the gradient magnitude and applies a threhold to find the regions of the images that are considered to be edges.

Run Sobel Edge Detection Algorithm on Test Image

The Sobel filtering algorithm operates on grayscale images. Convert the color image to an equivalent grayscale image with normalized values (0.0 for black, 1.0 for white).

im = imread('hello.jpg');
imGray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) +...
     0.1140 * double(im(:,:,3)))/255;
imSize = size(imGray);
figure();
image(im);
title('Test Image');

Figure contains an axes object. The axes object with title Test Image contains an object of type image.

Write the matrix gray into the imputImage.csv file using the writematrix command. The Sobel edge detection application reads in this CSV file.

writematrix(reshape(imGray,1,[]),'inputImage.csv');
imOut = sobelEdge(double(imGray));

To display the edge detected image, reformat the matrix imOut with the function repmat so that you can pass it to the image command.

figure();
image(repmat(imOut,[1 1 3]));
title('Edge Detected Image in MATLAB');

Figure contains an axes object. The axes object with title Edge Detected Image in MATLAB contains an object of type image.

Create Custom Main Function for sobelEdge.m

This example uses a custom main file, main_sobel.cu and its associated header file main_sobel.h. This custom main file reads the input image from the inputImage.csv file, calls the sobelEdge function in the generated sobelEdge.cu file, and saves the data from the edge detected image into the outputMag.csv file.

Package Generated Code Using the GPU Coder App

Open the GPU Coder app. In the MATLAB Toolstrip, in the Apps tab, under Code Generation, click GPU Coder.

In the GPU Coder panel, click Add Entry Points. In the Entry Points tab, enter the name of the entry-point function, sobelEdge.m. Specify that the input matrix Image uses the double data type and is variable-sized with at most 1024 rows and 1024 columns. To specify a dimension with an upper bound of 1024, enter :1024.

Entry Points tab showing Image as a double of size :1024 x :1024

In the toolstrip, in the GPU Coder tab, set the Output Type to Executable. You can also package the code generated for source code, static library, or dynamic library targets. You cannot package the code generated for MEX targets.

Click Settings to open the Standalone Code Generation Settings dialog box. In the left pane, click Custom Code. Then, in the Custom C Code for Generated Files section, set Additional source files to main_sobel.cu.

Custom Code pane showing main_sobel.cu specified as an additional source file

To generate code and build an executable, in the MATLAB Toolstrip, in the GPU Coder tab, click Generate Code and Build. The MATLAB Command Window shows the output from the build.

In the GPU Coder tab, click Export > Package as a Flat ZIP File. You can also package the generated code in a hierarchical ZIP file. Choose where to save the ZIP file, and then click Save.

The ZIP file contains the CUDA C++ code and header files required for relocation. It does not contain:

  • Compile flags

  • Defines

  • Makefiles

  • Example main files, unless you configure code generation to generate and compile the example main function

Inspect the contents of sobelEdge_pkg.zip in your working folder to verify that it is ready for relocation to the destination system. Depending on the ZIP tool that you use, you can open and inspect the file without unpacking it. You can now relocate the ZIP file to the desired development environment and unpack the file.

Package Generated Code at the Command Line

To generate a CUDA executable for the sobelEdge function, create a GPU code configuration object and run the codegen command.

cfg = coder.gpuConfig('exe');
cfg.GenerateReport = true;
cfg.CustomSource = 'main_sobel.cu';
inputArgs = {coder.typeof(0,[1024 1024],[1 1])};
codegen -config cfg sobelEdge -args inputArgs
Code generation successful: View report

To package the generated code into a zip file, load the BuildInfo object. The BuildInfo object contains information for compiling and linking generated code, including the list of all the source and include files and their paths.

buildInfoFile = fullfile(pwd,'codegen','exe','sobelEdge', ...
    'buildInfo.mat');
load(buildInfoFile);

Create the zip file by using the packNGo function.

packNGo(buildInfo,'packType','flat','nestedZipFiles',true,...
    'minimalHeaders',false,'includeReport',false);

The packNGo function creates the sobelEdge.zip file in the current working folder. This zip file contains the CUDA C++ code and header files required for relocation. It does not contain:

  • Compile flags

  • Defines

  • Makefiles

  • Example main files, unless you configure code generation to generate and compile the example main function.

Inspect the contents of sobelEdge.zip in your working folder to verify that it is ready for relocation to the destination system. Depending on the zip tool that you use, you can potentially open and inspect the file without unpacking it. You can now relocate the resulting zip file to the desired development environment and unpack the file.

Standalone Code Execution

When you execute the generated standalone executable, the output magnitudeData is computed and written to a comma-separated file. Read this output back in MATLAB and use the image function to visualize the edge detected image.

if ispc
    system('sobelEdge.exe');
else
    system('./sobelEdge');
end

imOutGPU = reshape(readmatrix('outputMag.csv'),imSize);
edgeImg = repmat(imOutGPU,[1 1 3]);
figure();
image(edgeImg);
title('Edge Detected Image on the GPU');

Figure contains an axes object. The axes object with title Edge Detected Image on the GPU contains an object of type image.

Specify packNGo Options

You can specify options for the packNGo function.

ToSpecify

Change the structure of the file packaging to hierarchical.

packNGo(buildInfo,'packType','hierarchical');

Change the structure of the file packaging to hierarchical and rename the primary zip file.

packNGo(buildInfo,'packType','hierarchical',...
'fileName','zippedsrcs');

Include all header files found on the include path in the zip file (rather than the minimal header files required to build the code).

For GPU Coder, this option must be set to false.

packNGo(buildInfo,'minimalHeaders',false);

Generate warnings for parse errors and missing files.

packNGo(buildInfo,'ignoreParseError', true,...
'ignoreFileMissing',true);

For more information, see packNGo.

Choose a Structure for the Zip File

Before you generate and package the files, decide whether you want to package the files in a flat or hierarchical folder structure. By default, the packNGo function packages the files in a single, flat folder structure. This approach is the simplest and might be the optimal choice.

IfUse
You are relocating files to an IDE that does not use the generated makefile, or the code is not dependent on the relative location of required static files A single, flat folder structure
The target development environment must maintain the folder structure of the source environment because it uses the generated makefile, or the code depends the relative location of filesA hierarchical structure

If you use a hierarchical structure, the packNGo function creates two levels of zip files. There is a primary zip file, which in turn contains the following secondary zip files:

  • mlrFiles.zip — files in your matlabroot folder tree

  • sDirFiles.zip — files in and under your build folder where you initiated code generation

  • otherFiles.zip — required files not in the matlabroot or start folder trees

Paths for the secondary zip files are relative to the root folder of the primary zip file, maintaining the source development folder structure.

See Also

Functions

Topics