1 時間 (未満) で SYCL* を学ぶ

インテル® DPC++/C++ コンパイラー

この記事は、The Parallel Universe Magazine 56 号に掲載されている「Learn SYCL* in an Hour (Maybe Less)」の日本語参考訳です。原文は更新される可能性があります。原文と翻訳文の内容が異なる場合は原文を優先してください。


parallel_v56_05

この記事では、C++ with SYCL* でプログラミングするために知っておくべき重要なことを紹介します。

ここでは最低限の要点のみ説明します。SYCL* に関する 500 ページの本に書かれていることをすべて伝えようとしているわけではありませんのでご安心ください。

基本を学んだ後、必要に応じてさらなる調査に使用できる小さなプログラムについて説明します。

SYCL* とは?

C++ with SYCL* を使用すると、ベンダー (NVIDIA、AMD、インテルなど) やアーキテクチャー (GPU、CPU、FPGA、DSP など) に関係なく、C++ プログラムからアクセラレーターを使用できるようになります。そのためには、SYCL* をサポートする C++ コンパイラーと、アクセラレーターをサポートするランタイム (ほとんどの場合、ベンダーの OpenCL* ランタイムなどのドライバー) が必要です。SYCL* 2020 (現在の標準規格) では、OpenCL* 以外もサポートしています。このおかげで、SYCL* の実装では、NVIDIA の PTX、AMD の ROCm*/HIP、多くのベンダーの OpenCL*、インテルの SPIR-V*、複数ベンダーの OpenMP* など、さまざまな方法でハードウェアへの最適なパスを見つけることができます。インテル® コンパイラーはこれらのパスのいくつかを使用します。ハイデルベルク大学主導の SYCL* コンパイラー・プロジェクト (AdaptiveCpp) は、多くの革新的なパスを拓いたことでよく知られています。さまざまなアクセラレーターの SYCL* サポートを取得するための、多くのオプションがあります。

SYCL* は C++

SYCL* は C++ 向けに設計されていて、C++ プログラマーにとって非常に使いやすいものです。最小限の C++ の知識があれば、SYCL* を学習して使用できます。

示された手順に従う

C++ の知識を最大限に活用するには、tinyurl.com/learnSYCLnow (英語) の「Learn SYCL in an Hour (Maybe Less) (1 時間 (未満) で SYCL* を学ぶ)」の手順に従ってください。この手順では、インテル® Tiber™ デベロッパー・クラウドにアクセスして、複数の GPU と必要なソフトウェアがインストールされた設定済みのシステムを使用する方法を説明しています。GitHub* からコード例を取得する方法についての情報も含まれています。

SYCL* には 3 つの鍵がある

SYCL* は、3 つの問題を解決する鍵として、次の機能を提供します。

  1. 実行時に利用可能なアクセレーターの確認。
  2. アクセラレーターとのデータの共有。
  3. アクセラレーターへの計算のオフロード。

SYCL* には、オフロード計算の C++ エラー処理のサポートや、リダクション操作のビルトインサポートなど、便利な多くの追加機能が用意されています。これらの機能は、3 つの鍵をよく理解した後、必要に応じて学習すると良いでしょう。

アクセラレーターの検索/選択

アクセラレーターを検索/選択する際の目標は、アクセラレーターへの接続を取得して、データの共有とコードのオフロードができるようにすることです。SYCL* 用語では、これはキューを取得することを意味します。

キューは特定のアクセラレーターに接続します。キューは好きなだけ作成できます。必要に応じて、異なるキューを同じアクセラレーターに紐づけることもできます。サンプルプログラムでは、マシン上のすべてのアクセラレーターへのハンドルをキューの配列に埋め込みます。つまり、1 つだけ取得できる場合もあれば、複数取得できる場合もあります。インテル® Tiber™ デベロッパー・クラウドの手順に従うと、4 つ得られるでしょう (少なくともこの記事の執筆時点ではそうなっています)。

SYCL* は、実行時に利用可能なアクセラレーターを検索して選択する多くの制御を提供します。単純なコードから始めます。

sycl::queue q;

これで、すべてのデータ共有とオフロードに使用するハンドル q が得られます。この単純なケースでは、SYCL* ランタイムは単純にアクセラレーターを選択します。

私は通常、早い段階で名前空間 sycl を使用する sycl:: キーワードを削除しますが、ここでは SYCL* を使用している部分が分かるように残しています。

SYCL* には常に利用可能なデバイスがあることに注意することが重要です。これは、常に動作する単純なプログラムを作成するときに非常に役に立ちます。アクセラレーターがないシステムでは、ホスト (私がこれまで見たすべての実装では CPU) が使用されます。

接続したデバイスを知りたい場合は、名前を出力します。

std::cout << "Running on " << q.get_device().get_info<sycl::info::device::name>();

アクセラレーターとのデータの共有

SYCL* ではデータの共有は簡単です。malloc に似たメモリー割り当てで USM (統合共有メモリー) を使用でき、その方法で割り当てられたメモリーはホストとアクセラレーター間で共有されます。通常は、ハードウェアで USM をサポートしているアクセラレーターでのみサポートされます。最新の GPU、CPU、FPGA は USM をサポートしているため、特に問題はありません。SYCL* は、ホストとアクセラレーター間で共有される明示的なバッファーもサポートしていますが、通常のポインターがホストとアクセラレーター間で動作することは許可していません。現時点では、バッファーを使用する場合を除いて、USM を使用することを推奨します。

サンプルプログラムでは円周率の桁を計算するジョブにバッファーを使用します。

タイトルとURLをコピーしました