他の開発環境への生成コードの移動
生成コードのファイルを、MATLAB® を含まないシステムや統合開発環境 (IDE) といった、他の開発環境に移動するには、コマンド ラインで関数 packNGo
を使用するか、GPU Coder™ アプリで [パッケージ] オプションを使用します。ファイルは圧縮ファイルにパッケージ化され、標準の zip ユーティリティを使用して移動および解凍できます。
GPU Coder を使用して生成されたコードは、サードパーティのコンパイラとライブラリを利用して実行可能ファイルのビルドと実行を行うため、移動先の開発環境もその要件を満たしていなければなりません。詳細については、前提条件となる製品のインストールと前提条件となる製品の設定を参照してください。
メモ
GPU Coder では、packNGo
コマンドの 'minimalHeaders'
オプションを false
に設定する必要があります。この設定は、コードをビルドするのに必要な最低限のヘッダー ファイルではなく、zip ファイル内のインクルード パスで見つかったヘッダー ファイルをすべてインクルードするよう、ソフトウェアに指示します。たとえば、packNGo(buildInfo,'minimalHeaders',false)
のようにします。
GPU Coder を使用した生成コードのパッケージ化
この例では、GPU Coder アプリの [パッケージ] オプションを使用して、移動用に生成コードを zip ファイルにパッケージ化する方法を説明します。この例では、ソーベル エッジ検出アプリケーションを使用してこの概念を説明します。既定では、GPU Coder は現在の作業フォルダーに zip ファイルを作成します。
必要条件
NVIDIA® CUDA® 対応 GPU
CUDA Toolkit およびドライバー。
サポートされているコンパイラおよびライブラリのバージョンの詳細については、サードパーティ ハードウェアを参照してください。環境変数の設定は、前提条件となる製品の設定を参照してください。
ソーベル エッジ検出エントリポイント関数
ソーベル エッジ検出アルゴリズムでは、グレースケール イメージに対する 2 次元の空間勾配演算が行われます。この演算は、エッジに相当する空間周波数の高い領域を強調します。
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
ソーベル エッジ検出アルゴリズムは、2 つの直交フィルター カーネル (maskX
と maskY
) を使用して、入力イメージの水平方向勾配 (resX
) と垂直方向勾配 (resY
) を計算します。このアルゴリズムは、フィルター処理演算を実行した後、勾配の大きさを計算してしきい値を適用し、エッジと考えられるイメージの領域を見つけます。
テスト イメージに対するソーベル エッジ検出アルゴリズムの実行
ソーベル フィルター処理アルゴリズムは、グレースケール イメージに作用します。カラー イメージを、正規化された値をもつ (黒が 0.0、白が 1.0) 等価なグレースケール イメージに変換します。
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');
writematrix
コマンドを使用して、グレースケール イメージの行列を imputImage.csv
ファイルに書き込みます。ソーベル エッジ検出アプリケーションが、この CSV ファイルを読み取ります。
writematrix(reshape(imGray,1,[]),'inputImage.csv');
imOut = sobelEdge(double(imGray));
エッジが検出されたイメージを表示するには、関数 repmat
を使用して行列 imOut
を再構築し、image
コマンドに渡せるようにします。
figure();
image(repmat(imOut,[1 1 3]));
title('Edge Detected Image in MATLAB');
sobelEdge.m
用カスタム main 関数の作成
この例では、カスタム メイン ファイル main_sobel.cu
および関連するヘッダー ファイル main_sobel.h
を使用します。このカスタム メイン ファイルは、inputImage.csv
ファイルから入力イメージを読み取り、生成された sobelEdge.cu
ファイルの関数 sobelEdge
を呼び出し、エッジが検出されたイメージのデータを outputMag.csv
ファイルに保存します。
GPU Coder アプリを使用した生成コードのパッケージ化
GPU Coder アプリを開きます。MATLAB ツールストリップの [アプリ] タブにある [コード生成] で、GPU Coder アプリ アイコンをクリックします。
[ソース ファイルの選択] ページで、エントリポイント関数の名前「sobelEdge.m
」を入力します。[次へ] をクリックして [入力の型を定義] ページに進みます。
入力 Image
が可変サイズ (上限が 1024) の double データ型であることを指定します。上限が 1024 の可変サイズを指定するには、:1024
を選択します。[次へ] をクリックして [実行時の問題の確認] ページに進みます。
実行時の問題をチェックします。[実行時の問題の確認] ダイアログ ボックスで、double の入力を使用して sobelEdge
を呼び出すコードを入力します。たとえば、sobelEdge(ones(648,484))
のようにします。[問題の確認] をクリックします。実行時の問題を確認するため、アプリによって MEX 関数が生成され、実行されます。アプリは sobelEdge
の問題を検出しません。[次へ] をクリックして [コードの生成] ページに進みます。
[生成] ダイアログ ボックスで、[ビルド タイプ] を [実行可能ファイル] に設定します。ソース コード、スタティック ライブラリ、またはダイナミック ライブラリのターゲット用に生成されたコードをパッケージ化することもできます。MEX ターゲット用に生成されたコードをパッケージ化することはできません。[詳細設定] をクリックします。
[生成されたファイルのカスタム C コード] の [カスタム コード] タブで、[追加ソース ファイル] を main_sobel.cu
に設定します。[閉じる] をクリックして [コードの生成] ページに進みます。
[生成] をクリックします。[次へ] をクリックして [ワークフローの完了] ページに進みます。[ワークフローの完了] ページで、[パッケージ] をクリックします。
[パッケージ] ダイアログ ボックスで、パッケージ ファイル名とパッケージ化のタイプを指定します。既定では、アプリはプロジェクト名からパッケージ ファイル名を導出します。アプリは、現在の作業フォルダーにファイルを保存します。既定では、アプリは生成されたファイルを単一でサブフォルダーのないフォルダーとしてパッケージ化します。この例の場合、既定の値を使用し、[保存] をクリックします。
この zip ファイルには、移動に必要な CUDA C++ コードとヘッダー ファイルが格納されています。以下のものは含まれません。
コンパイル フラグ
定義
makefile
メイン ファイルの例 (main 関数の例の生成とコンパイルを行うようにコード生成を設定した場合を除く)
作業フォルダー内の sobelEdge_pkg.zip
の内容を検査し、移動先のシステムに移動する準備が整っているか確認します。使用する zip ツールによっては、解凍せずにファイルを開いて内容を検査できます。これで、得られた zip ファイルを目的の開発環境に移動して解凍できるようになりました。
コマンド ラインでの生成コードのパッケージ化
関数 sobelEdge
用の CUDA 実行可能ファイルを生成するには、GPU コード構成オブジェクトを作成して codegen
コマンドを実行します。
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
生成コードを zip ファイルにパッケージ化するには、BuildInfo
オブジェクトを読み込みます。BuildInfo
オブジェクトには、生成コードをコンパイルしてリンクするのに必要な情報 (すべてのソースとインクルード ファイルの一覧、およびそれらのパス) が格納されています。
buildInfoFile = fullfile(pwd,'codegen','exe','sobelEdge', ... 'buildInfo.mat'); load(buildInfoFile);
関数 packNGo
を使用して、zip ファイルを作成します。
packNGo(buildInfo,'packType','flat','nestedZipFiles',true,... 'minimalHeaders',false,'includeReport',false);
関数 packNGo
は、現在の作業フォルダーに sobelEdge.zip
ファイルを作成します。この zip ファイルには、移動に必要な CUDA C++ コードとヘッダー ファイルが格納されています。以下のものは含まれません。
コンパイル フラグ
定義
makefile
メイン ファイルの例 (main 関数の例の生成とコンパイルを行うようにコード生成を設定した場合を除く)
作業フォルダー内の sobelEdge.zip
の内容を検査し、移動先のシステムに移動する準備が整っているか確認します。使用する zip ツールによっては、解凍せずにファイルを開いて内容を検査できます。これで、得られた zip ファイルを目的の開発環境に移動して解凍できるようになりました。
スタンドアロン コードの実行
生成されたスタンドアロン実行可能ファイルを実行すると、出力 magnitudeData
が計算されてコンマ区切りのファイルに書き込まれます。この出力を MATLAB に読み戻し、関数 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');
packNGo のオプションの指定
関数 packNGo
のオプションを指定できます。
目的 | Specify |
---|---|
ファイルのパッケージ化の構造を階層構造に変更する。 | packNGo(buildInfo,'packType','hierarchical'); |
ファイルのパッケージ化の構造を階層構造に変更し、プライマリ zip ファイルの名前を変更する。 | packNGo(buildInfo,'packType','hierarchical',... |
コードをビルドするのに必要な最低限のヘッダー ファイルではなく、zip ファイル内のインクルード パスで見つかったヘッダー ファイルをすべてインクルードする。 GPU Coder では、このオプションを false に設定しなければなりません。 | packNGo(buildInfo,'minimalHeaders',false); |
解析エラーと不足しているファイルの警告を生成する。 | packNGo(buildInfo,'ignoreParseError', true,... |
詳細については、packNGo
を参照してください。
zip ファイルの構造の選択
ファイルを生成してパッケージ化する前に、サブフォルダーがないフォルダー構造にするか、階層的なフォルダー構造にするか決定してください。既定では、関数 packNGo
はファイルを単一でサブフォルダーのない構造としてパッケージ化します。通常はこの方法が最も簡潔で最適な選択肢です。
条件 | 使用 |
---|---|
生成された makefile を使用しない IDE にファイルを移動するつもりである。または、必要な静的ファイルの相対位置を利用しないコードである | 単一でサブフォルダーのない構造 |
生成された makefile を移動先の開発環境で使用する、またはコードがファイルの相対位置を利用するため、移動先の開発環境において移動元の開発環境のフォルダー構造を維持しなければならない | 階層構造 |
階層構造を使用する場合、関数 packNGo
によって 2 重の zip ファイルが作成されます。プライマリ zip ファイルの中に、次のセカンダリ zip ファイルが格納されます。
mlrFiles.zip
—
フォルダー ツリー内にあるファイルmatlabroot
sDirFiles.zip
— コード生成を開始したビルド フォルダー配下のファイルotherFiles.zip
—
またはmatlabroot
start
フォルダー ツリー内にない必須ファイル
セカンダリ zip ファイルへのパスは、プライマリ zip ファイルのルート フォルダーからの相対パスとなり、移動元の開発環境のフォルダー構造が維持されます。