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
NVIDIA® CUDA® enabled GPU
CUDA toolkit and drivers.
For information on the supported versions of the compilers and libraries, see Third-Party Hardware. For setting up the environment variables, see Setting Up the Prerequisite Products.
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');
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');
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
.
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
.
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');
Specify packNGo Options
You can specify options for the packNGo
function.
To | Specify |
---|---|
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',... |
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,... |
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.
If | Use |
---|---|
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 files | A 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
folder treematlabroot
sDirFiles.zip
— files in and under your build folder where you initiated code generationotherFiles.zip
— required files not in the
ormatlabroot
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.