移行ワークフローのガイドライン
説明
移行ワークフローのガイドライン#
概要#
CUDA* から SYCL* へのコード移行ワークフローは、次のステージで構成されます。
ステージ 1: 移行の準備。移行を成功させるためプロジェクトを準備し、ツールを構成します。
ステージ 2: コードを移行。ツールのオプションを確認し、ツールを使用してコードを移行します。
ステージ 3: 移行されたコードを確認。移行されていないコードを確認し、手動で変換します。
ステージ 4: 新しい SYCL* コードベースをビルド。移行されたコードからプロジェクトをビルドします。
ステージ 5: 新しい SYCL* アプリケーションの評価。移行後の新しい SYCL* アプリケーションを検証して、正しく機能するか確認します。
このドキュメントでは、一般的な推奨事項とオプションの手順とともに、各ステージの手順について説明します。
注
CUDA* API の移行サポートは広範囲にわたりますが、完全ではありません。ツールのサポート不足により移行されなかった CUDA* API に遭遇した場合は、Migrating to SYCL フォーラム (英語) または優先サポート (英語) に報告してください。あるいは、問題を提供 (英語) するか、SYCLomatic プロジェクトに貢献 (英語) してください。情報を提供いただくことで、将来のリリースでサポートされる CUDA* API の優先順位付けが容易になります。
必要条件#
インテル® DPC++ 互換性ツールをインストールします。インテル® DPC++ 互換性ツールは、インテル® oneAPI ベース・ツールキットに含まれています。ベースキットをインストールしていない場合、インテル® oneAPI ツールキットとコンポーネントのインストール (英語) の手順に従ってください。
インテル® DPC++ 互換性ツールは、スタンドアロン製品としてダウンロードすることもできます。スタンドアロン・ツールをダウンロード (英語)。
ツール 環境をセットアップします。セットアップに関する情報は、インテル® DPC++ 互換性ツールの導入ガイド (英語) を参照してください。
ステージ 1: 移行の準備#
CUDA* コードを SYCL* に移行する前に、移行用に CUDA* ソースコードを準備します。
CUDA* プロジェクトの準備#
移行中のエラーを最小限に抑えるため、移行前に CUDA* プロジェクトを準備することを推奨します。
CUDA* ソースコードに構文エラーがないことを確認してください。
CUDA* ソースコードが Clang 互換であることを確認してください。
構文エラーを修正#
元の CUDA* ソースコードに構文エラーがある場合、移行が失敗する可能性があります。
移行を開始する前に、元の CUDA* ソースコードが正しくビルドでき、実行できることを確認してください。
元の CUDA* プロジェクト用に定義されたコンパイラーを使用して、元のソースコードをコンパイルします。
コンパイルされたアプリケーションを実行し、期待どおりに機能することを確認します。
コードがビルドエラーなしでコンパイルされ、アプリケーションが期待どおりに動作することを確認したら、CUDA* プロジェクトは移行の準備が整っています。
Clang の互換性#
インテル® DPC++ 互換性ツールは、最新バージョンの Clang パーサーを使用して、移行中に CUDA* ソースコードを解析します。Clang パーサーは、 NVIDIA* CUDA コンパイラー・ドライバー (nvcc) と必ずしも互換性があるわけではありません。このツールは、移行中に nvcc と Clang 間の非互換性に関するエラーを出力します。
場合によっては、移行前に CUDA* ソースを手動で編集する必要があることがあります。次に例を示します。
Clang パーサーでは、nvcc が名前空間修飾を必要としない特定の使用シナリオで、名前空間修飾が必要になる場合があります。
Clang パーサーでは、nvcc で必要ない追加の前方クラス宣言が必要になる場合があります。
カーネル呼び出しの三重括弧内のスペースは、nvcc では許容されますが、Clang では許容されません。たとえば、
cuda_kernel<< <num_blocks, threads_per_block>> >(args…)
は nvcc では問題ありませんが、Clang パーサーではスペースを削除する必要があります。
nvcc と Clang パーサー間の互換性の問題が解決されていない CUDA* ソースコードで移行ツールを実行すると、移行結果に次のようなエラーが混在します。
Clang errors, which must be resolved in the CUDA source code (Clang エラーは CUDA* ソースコードで解決する必要があります)
DPCT warnings, which must be resolved in the migrated SYCL code (DPCT 警告。移行された SYCL コードで解決する必要があります)
Clang と nvcc の語彙の違いの詳細については、llvm.org の Clang を使用した CUDA* のコンパイル (英語) ページを参照してください。
CodePin を実行してアプリケーションの署名を取得#
CodePin は、実行時の動作の不一致をデバッグする労力を軽減する機能です。CodePin は、CUDA* プログラムと SYCL* プログラムから生成されたレポートを比較して、実行時の動作の相違となる原因を特定するのに役立ちます。
プロジェクトの署名を取得するには、移行中に CodePin ツールを有効にします。
この署名は、移行後の検証に使用されます。
CodePin を有効にするには、–enable-codepin
オプションを使用します。
CodePin ツールを使用したデバッグの詳細については、移行されたコードの実行時動作のデバッグ (英語) を参照してください。
ツールを設定#
プロジェクトで使用される CUDA* ヘッダーファイルは、ツールがアクセスできる必要があります。できない場合は、ツールを構成して、ヘッダーファイルが使用可能であることを確認します。
インストールとセットアップに関する情報は、インテル® DPC++ 互換性ツールの導入ガイド (英語) を参照してください。
コンパイルコマンドを記録#
intercept-build
を使用してコンパイル・データベースを生成し、プロジェクトの詳細なビルドオプションを取得します。移行ツールは、データベースからのビルド情報 (ヘッダーファイルのパス、インクルード・パス、マクロ定義、コンパイラー・オプション、元のコンパイラーなど) を使用して、CUDA* コードの移行をガイドします。
開発環境で intercept-build を使用できない場合は、他のビルドシステムでコンパイル・データベースを生成するで説明されている代替方法を使用します。
注
元の移行後に CUDA* ビルドスクリプトが変更されて移行を再実行する場合は、次のいずれかを行う必要があります。
移行で使用する更新されたコンパイル・データベースを取得するため intercept-build を再実行するか、
更新された CUDA* ビルドスクリプトの変更を取得するには、コンパイル・データベースを手動で更新します。
リビジョン管理の設定#
移行後は、ベンダー依存を回避するために、移行したアプリケーションを SYCL* で保守および開発することを推奨しますが、CUDA* でアプリケーション開発を継続することもできます。CUDA* で開発を続行すると、再度 CUDA* から SYCL* に移行する必要が生じます。
リビジョン管理により、移行されたコードのバージョン間の比較が可能になり、SYCL* コードに対する以前の手動による変更のうち、新しく移行されたコードにマージするものを決定するのに役立ちます。
最初の移行の前に、元の CUDA* ソースのリビジョン管理を必ず行ってください。最初の移行後、移行された SYCL* コードと、その後のすべての手動による SYCL* 変更も、必ずリビジョン管理下に置いてください。
解析モードの実行#
解析モードを使用すると、移行前にレポートを生成できます。このレポートには、移行されるコードの量、部分的に移行されるコードの量、およびツールの実行後に移行の完了に必要な手動作業の見積もりが示されます。これは、移行に必要な作業を見積もるのに役立ちます。
ステージ 2: コードを移行#
移行の計画#
移行を開始する前に、移行を計画するために使用できるツールの機能とオプションを確認してください。
移行のルール#
このツールは、すべての移行においてデフォルトの移行ルールセットを使用します。デフォルトのルールで必要とする移行結果が得られない場合、カスタムルールを定義できます。これは、次のような複数のシナリオで役立ちます。
移行後、移行されなかった類似する、または同一の CUDA* ソースコードの複数のインスタンスが見つかり、CUDA* ソースコードを SYCL* に移行する方法が判明している場合。この場合、カスタムルールを定義して移行を再実行し、より良い結果を得ることができます。これは、増分移行や、時間の経過とともに複数の移行を実行する可能性があるシナリオに役立ちます。
移行前に、元の CUDA* ソースの一部のコードパターンが、ビルトインルールでは SYCL* に正確に移行されないことが判明している場合。この場合、移行中に CUDA* ソース内の特定のパターンを処理するカスタム移行ルールを定義できます。
カスタムルールを定義する詳細については、移行ルールを参照してください。
実際のカスタムルールの例については、ツールのインストール・パスの extensions/opt_rules
フォルダーにあるオプションの定義済みルールを参照してください。
段階的な移行#
インテル® DPC++ 互換性ツールは、複数の移行結果を単一の移行済みプロジェクトに自動的にマージする段階的な移行を可能にします。
段階的な移行を行うと、CUDA* プロジェクトを段階的に移行できます。
例えば、一度に 10 個のファイルを移行できます。
新しい CUDA* ファイルを移行済みのプロジェクトに移行できます。
複数のコードパスを移行できます。
段階的な移行はデフォルトで有効になっています。--no-incremental-migration
オプションで段階的な移行を無効にできます。
増分移行の詳細情報と例については、増分移行を参照してください。
コマンドライン・オプション#
インテル® DPC++ 互換性ツールには、移行を指示する多くのコマンドライン・オプションが用意されています。コマンドライン・オプションは、基本オプションと詳細オプションを使用して移行の構成を制御することができます。
使用可能なコマンドライン・オプションの完全なリストについては、アルファベット順のオプションリストを参照してください。
バッファーと USM コードの生成#
インテルは、SYCL*/oneAPI コンテキストでバッファーと USM の両方を推進しています。一部の oneAPI ライブラリーは USM よりもバッファーを優先的にサポートするため、移行を構成する際には設計上の考慮が必要になる場合があります。デフォルトでは USM が使用されますが、一部のプロジェクトではバッファーの方が適する場合があります。
バッファーモデルは、1 から 3 次元配列 (バッファー) を設定し、C++ アクセサークラスを介してそのコンポーネントにアクセスします。これにより、割り当てられたメモリーの正確な性質とサイズ、およびホストとオフロードターゲットの計算ユニットがメモリーにアクセスする方法を細かく制御できるようになります。ただし、バッファーモデルではクラス管理のオーバーヘッドが発生する可能性があり、手動による介入が増え、パフォーマンスが低下することがあります。
USM (統合共有メモリー) は、SYCL2020 以降の新しいモデルです。USM は、malloc_device/malloc_shared/malloc_host
アロケーター関数を使用するポインターベースのメモリー管理モデルであり、GPU デバイスのオフロードが関係しない場合に C++ コードが通常メモリーアクセスを処理する方法に類似しています。USM モデルを選択すると、既存のコードへの追加や CUDA* コードからの移行が容易になります。ただし、USM メモリー空間の管理はほとんどが SYCL* ランタイムによって実行されるため、開発者による制御の粒度が低下します。
SYCL* バッファー 仕様 (英語)
SYCL* USM 仕様 (英語)
USM モードとバッファーモードの詳細については、GPU 最適化ガイドの次のセクションを参照してください。* 統合共有メモリー割り当て * バッファー・アクセサー・モード
移行されたコードに期待されること#
ツールが CUDA* コードを SYCL* コードに移行すると、移行されたコードに診断メッセージがコメントとして挿入されます。DPCT 診断メッセージは、移行されたソースファイルにコメントとして記録され、移行中にコンソールに警告として出力されます。これらのメッセージは、コードを SYCL* 準拠または修正するのに注意が必要な、移行されたコードの領域を識別します。このステップの詳細はステージ 3 で説明します。移行されたコードを確認します。
移行されたコードは、生成された SYCL* コードのユーティリティー・サポートを提供する DPCT ヘルパー関数も使用します。ヘルパー関数は dpct:: 名前空間
を使用します。ヘルパー関数のソースファイルは、<tool-installation-directory>/latest/include/dpct
にあります。DPCT ヘルパー関数は移行されたコードに残しておくことができますが、新しい SYCL* コードでは使用しないでください。新しいコードを記述するときは、標準の SYCL* と C++ を使用します。DPCT 名前空間の詳細については、DPCT 名前空間リファレンスを参照してください。
移行の実行#
利用可能な移行ツールの機能とオプションを確認した後、移行を行います。
このツールは、コマンドラインから、または Microsoft Visual * または Eclipse* IDE 内で実行できます。
プロジェクトで Makefile または CMake ファイルを使用する場合、対応するオプションを使用して、移行されたコードで動作するようにファイルを自動的に移行します。
Makefile を移行するには、
--gen-build-scripts
オプションを使用します。CMake ファイルを移行するには、
--migrate-build-script
または--migrate-build-script-only
オプションを使用します。(これらのオプションは実験的なものであることを留意してください。)
次に例を示します。
c2s -p compile_commands.json --in-root ../../.. --gen-helper-function --gen-build-scripts
この例の移行コマンドを示します:
ツールエイリアス
c2s
を使用します。dpct
も使用できます。-p
オプションで指定されたコンパイル・データベースを使用します--in-root
オプションで移行するソースを指定します--gen-helper-function
オプションを使用してツールにヘルパー関数ファイルを生成するように指示します--gen-build-scripts
オプションを使用して Makefile を移行するようにツールに指示します。
次のサンプルは、ツールを使用して CUDA* コードを移行し、インテルおよび NVIDIA* ハードウェアをターゲットにしている例です。
同時実行カーネルのサンプル (英語)
ステージ 3: 移行されたコードを確認#
インテル® DPC++ 互換性ツールを実行した後、移行された SYCL* コードをコンパイルする前に、通常は手動で編集する必要があります。DPCT の警告は移行されたソースファイルにコメントとして記録され、移行中にコンソールに出力されます。これらの警告は、手動による介入が必要なコード部分を示します。これらのコメントを確認し、推奨される変更を加えて、移行されたコードが元のロジックと一致するようにします。
例えば、以下のオリジナル CUDA* コードについて考えてみます。
1 void foo() {
2 float *f;
3 cudaError_t err = cudaMalloc(&f, 4);
4 printf("%s\n", cudaGetErrorString(err));
5 }
このコードは、以下の SYCL* コードに移行されます。
1 void foo() {
2 float *f;
3 int err = (f = (float *)sycl::malloc_device(4, dpct::get_default_queue()), 0);
4 /*
5 DPCT1009:1: SYCL uses exceptions to report errors and does not use the error
6 codes.The original code was commented out and a warning string was inserted.
7 You need to rewrite this code.
8 */
9 printf("%s\n",
10 "cudaGetErrorString is not supported" /*cudaGetErrorString(err)*/);
11 }
追加の確認が必要な場所に挿入される DPCT1009 警告に注意してください。
問題を修正する提案を含むコメントの詳細な説明については、診断リファレンスを参照してください。
このステージでは、コード内で同じ DPCT 警告が繰り返し生成されたり、元のソースコードの特定のパターンを修正するため複数の場所で同じ編集が必要になったりすることがあります。繰り返し発生する DPCT 警告を修正する手動での編集を、ユーザー定義の移行ルールとして定義することを検討してください。これにより、修正内容を保存し、CUDA* ソースの将来の移行に自動的に適用できるようになります。
注
CUDA* API の移行サポートは広範囲にわたりますが、完全ではありません。ツールのサポート不足により移行されなかった CUDA* API に遭遇した場合は、Migrating to SYCL フォーラム (英語) または優先サポート (英語) に報告してください。あるいは、問題を提供 (英語) するか、SYCLomatic プロジェクトに貢献 (英語) してください。情報を提供いただくことで、将来のリリースでサポートされる CUDA* API の優先順位付けが容易になります。
ステージ 4: 新しい SYCL* コードベースをビルド#
手動での移行手順を完了したら、変換されたコードをビルドします。
新しい SYCL* コードベースの依存関係をインストール#
変換されたコードは、oneAPI ライブラリー API とインテルの SYCL* 拡張機能を利用します。コンパイルする前に、適切な oneAPI ライブラリーとインテルの SYCL* 拡張をサポートするコンパイラーをインストールします。
CUDA* ソースが以下を使用している場合 ... |
... oneAPI ライブラリーをインストールします |
---|---|
cuBLAS、cuFFT、cuRAND、cuSolver、cuSparse |
インテル® oneAPI マス・カーネル・ライブラリー (oneMKL) |
Thrust、CUB |
インテル® oneAPI DPC++ ライブラリー (oneDPL) |
cuDNN |
インテル® oneAPI ディープ・ニューラル・ネットワーク・ライブラリー (oneDNN) |
NCCL |
インテル® oneAPI コレクティブ・コミュニケーション・ライブラリー (oneCCL) |
次のコンパイラーはインテルの SYCL* 拡張をサポートしています。
ほとんどのライブラリーとインテル® oneAPI DPC++/C++ コンパイラーは、インテル® oneAPI ベース・ツールキット (英語) に含まれています。ライブラリーとコンパイラーはスタンドアロンのダウンロードとしても提供されています。
インテル® CPU と GPU 向けにコンパイル#
プログラムがインテル® GPU をターゲットとしている場合、コンパイルする前に最新のインテル® GPU ドライバーをインストールしてください。
Linux* GPU ドライバー (英語)
Windows* GPU ドライバー (英語)
更新された Makefile または CMake ファイルを使用してプログラムをビルドするか、インテルの SYCL* 拡張をサポートするコンパイラーを使用してコマンドラインで手動でコンパイルします。すべてのリンカーおよびコンパイルコマンドが C++ ドライバーで -fsycl
コンパイラー・オプションを使用していることを確認します。次に例を示します。
icpx -fsycl migrated-file.cpp
インテル® oneAPI DPC++/C++ コンパイラーを使用したコンパイルの詳細については、『インテル® oneAPI DPC++/C++ コンパイラー・デベロッパー・ガイドおよびリファレンス』(英語) を参照してください。
AMD* または NVIDIA* GPU 向けにコンパイル#
プログラムが AMD* または NVIDIA* GPU をターゲットとしている場合、コンパイルする前にターゲット GPU に対応した Codeplay* プラグインをインストールしてください。AMD* および NVIDIA* GPU プラグインのインストール手順と、それらのターゲット用にコンパイルする方法については、Codeplay* プラグインのドキュメントを参照してください。
Codeplay* の AMD* GPU 用 oneAPI プラグインをインストール (英語) します。
Codeplay* の NVIDIA* GPU 用 oneAPI プラグインをインストール (英語) します。
ステージ 5: 新しい SYCL* アプリケーションの評価#
変換されたコードをビルドしたら、新しい SYCL* アプリケーションを検証して、移行後の機能が正しいかどうかを確認します。
デバッガーを使用して移行したコードを検証#
新しい SYCL* アプリケーションが正常にコンパイルできたら、インテル® ディストリビューションの GDB* などのデバッガーを使用してデバッグモードでアプリケーションを実行し、移行後にアプリケーションが期待どおりに実行されることを確認します。
インテル® ディストリビューションの GDB* (英語) を使用したデバッグの詳細をご覧ください。
CodePIN を使用して移行したコードを検証#
移行時に CodePin 機能が有効になっている場合、実行時にプロジェクト署名がログに記録されます。
署名にはそれぞれの実行チェックポイントのデータ値が含まれており、手動で検証することも、自動分析ツールを使用して検証することもできます。
CodePin ツールを使用したデバッグの詳細については、移行されたコードの実行時動作のデバッグ (英語) を参照してください。
コードの最適化#
インテル® VTune™ プロファイラー (英語) やインテル® Advisor (英語) などのインテルのツールを使用して、移行したコードをインテル® GPU 向けに最適化します。これらのツールは、アプリケーションのパフォーマンスを最適化するため改善すべきコード領域を特定するのに役立ちます。
追加のハードウェアまたはライブラリー固有の最適化情報が提供されています。
インテル® GPU 向けにコードを最適化する方法の詳細については、oneAPI GPU 最適化ガイドを参照してください。
AMD* GPU 向けにコードを最適化する方法の詳細については、Codeplay の AMD* GPU パフォーマンス・ガイドを参照してください。
NVIDIA* GPU 向けにコードを最適化する方法の詳細については、Codeplay の NVIDIA* GPU パフォーマンス・ガイドを参照してください。
さらに詳しく#
内容 |
説明 |
---|---|
インテル® oneAPI DPC++/C++ コンパイラー向けのデベロッパー・ガイドおよびリファレンス。 |
|
SYCL* 2020 仕様 (英語) |
SYCL* 2020 仕様の PDF です。 |
オープンソースの oneAPI DPC++ コンパイラーからビルドされ、インテル® ハードウェアの最適化が追加されたインテルブランドの C++ コンパイラー。 |
|
oneAPI DPC++ コンパイラー (英語) |
SYCL* 言語のコンパイラーとランタイムサポートを実装する、オープンソースのインテルの LLVM ベースのコンパイラー・プロジェクト。 |
基本移行のサンプル (英語) |
ツールを使用して SYCL* に移行する手順を含むサンプル CUDA* プロジェクト。 |
ガイド付き移行のサンプル |
NVIDIA* CUDA* プロジェクトのガイド付き移行の 2 つのサンプル :
|
Jupyter* ノートブックのサンプル (英語) |
CUDA* から SYCL* への移行の簡単な例と 4 つのステップバイステップのサンプルの移行をガイドする Jupyter* ノートブック。 |
SYCL* に移行された CUDA* プロジェクトのカタログ。 |
|
SYCL* への移行フォーラム (英語) |
CUDA* コードを SYCL* に移行する際にサポートを受けることができるフォーラム。 |
特定のユースケースに oneMKL ライブラリーを含める方法を決定するのに役立つインテル® oneAPI マス・カーネル・ライブラリーのツール。 |
|
このチュートリアルでは、インテル® ディストリビューションの GDB* を使用してアプリケーションをデバッグする基本的なシナリオについて説明します。 |
|
独自のアプリケーションに適用できる、インテル® VTune™ プロファイラーを使用したエンドツーエンドのワークフローを紹介するチュートリアルです。 |