SYCL™ 2020 仕様 (リビジョン 6)
Khronos® SYCL™ ワーキンググループ
2022-11-13 04:05:44Z: from git SYCL-2020/final-rev6 commit:
26269b35206a59d51062642f85894559eb9ee030

注意事項:
この日本語マニュアルは、Khronos Group のウェブサイト https://www.khronos.org/registry/SYCL/ (英語)で公開されている『SYCL 2020 Specification revision 6』の参考訳です。Khronos Group の許可を得て iSUS
(IA Software User Society) が翻訳版を作成した iSUS の著作物です。原文は Khronos Group の Copyright
であり、日本語参考訳版にも適用されます。

SYCL 2020 リビジョン 6

目次
第 1 章 謝辞 ................................................................................................................................................................................................................................................... 13
第 2 章 はじめに .......................................................................................................................................................................................................................................... 15
第 3 章 SYCL アーキテクチャー .......................................................................................................................................................................................................... 17
3.1. 概要 .................................................................................................................................................................................................................................................... 17
3.2. SYCL アプリケーションの構造............................................................................................................................................................................................. 173.3. 引用する規格................................................................................................................................................................................................................................. 19
3.4. 非規格の注記と例 ....................................................................................................................................................................................................................... 19
3.5. SYCL プラットフォーム・モデル............................................................................................................................................................................................ 19
3.6. SYCL バックエンド・モデル .................................................................................................................................................................................................... 20
3.6.1. プラットフォーム混在バージョンのサポート ...................................................................................................................................................... 21
3.7. SYCL 実行モデル........................................................................................................................................................................................................................ 21
3.7.1. SYCL アプリケーション実行モデル......................................................................................................................................................................... 21
3.7.1.1. SYCL アプリケーションによって管理される SYCL バックエンドのリソース ............................................................................ 22
3.7.1.2. SYCL コマンドグループと実行順序 .............................................................................................................................................................. 22
3.7.1.3. イベントによる実行順序の制御 ....................................................................................................................................................................... 24
3.7.2. SYCL カーネル実行モデル .......................................................................................................................................................................................... 24
3.7.2.1. 基本カーネル ............................................................................................................................................................................................................ 24
3.7.2.2. ND-range カーネル ............................................................................................................................................................................................... 24
3.7.2.3. バックエンド固有のカーネル ............................................................................................................................................................................ 25
3.8. メモリーモデル ............................................................................................................................................................................................................................. 25
3.8.1. SYCL アプリケーションのメモリーモデル ........................................................................................................................................................... 25
3.8.2. SYCL デバイスのメモリーモデル .............................................................................................................................................................................. 28
3.8.2.1. メモリーアクセス ..................................................................................................................................................................................................... 29
3.8.3. SYCL メモリー一貫性モデル ...................................................................................................................................................................................... 29
3.8.3.1. メモリー順序 ............................................................................................................................................................................................................. 30
3.8.3.2. メモリースコープ .................................................................................................................................................................................................... 31
3.8.3.3. アトミック操作 ......................................................................................................................................................................................................... 31
3.8.3.4. フォワードプログレス (進行).............................................................................................................................................................................. 32
3.9. SYCL プログラミング・モデル .............................................................................................................................................................................................. 32
3.9.1. C++ 最小バージョン要件 ............................................................................................................................................................................................. 32
3.9.2. C++ の将来のバージョンとの整合性 ...................................................................................................................................................................... 32
3.9.3. 基本データ並列カーネル .............................................................................................................................................................................................. 33
3.9.4. ｗork-group データ並列カーネル ........................................................................................................................................................................... 33
3.9.5. 階層データ並列カーネル .............................................................................................................................................................................................. 33
3.9.6. 並列インスタンスから起動されないカーネル ..................................................................................................................................................... 34
3.9.7. 事前定義カーネル ............................................................................................................................................................................................................ 34
3.9.8. 同期.......................................................................................................................................................................................................................................... 34

2 | 目次SYCL 2020 リビジョン 6
3.9.8.1. SYCL アプリケーションの同期 ........................................................................................................................................................................ 34
3.9.8.2. SYCL カーネルの同期 .......................................................................................................................................................................................... 35
3.9.9. エラー処理 ........................................................................................................................................................................................................................... 35
3.9.10.

フォールバックのメカニズム ............................................................................................................................................................................. 35

3.9.11.

カーネルのスケジュールとデータ移動 ......................................................................................................................................................... 36

3.9.12.

オブジェクトの存続期間を管理 ....................................................................................................................................................................... 36

3.9.13.

デバイスの検出と選択 .......................................................................................................................................................................................... 36

3.9.14.

SYCL バックエンド API とのインターフェイス ......................................................................................................................................... 37

3.10.

メモリー・オブジェクト..................................................................................................................................................................................................... 37

3.11.

多次元オブジェクトと線形化 ...................................................................................................................................................................................... 38

3.11.1.

線形化........................................................................................................................................................................................................................... 38

3.11.2.

多次元のインデックス操作 ................................................................................................................................................................................. 38

3.12.

実装オプション ................................................................................................................................................................................................................... 39

3.12.1.

単一ソース複数コンパイラー ........................................................................................................................................................................... 39

3.12.2.

単一ソース単一コンパイラー ........................................................................................................................................................................... 39

3.12.3.

ライブラリーのみの実装 ...................................................................................................................................................................................... 39

3.13.

カーネルの言語制限 ........................................................................................................................................................................................................ 40

3.13.1.

コピー可能なデバイス .......................................................................................................................................................................................... 40

3.14.

エンディアンのサポート................................................................................................................................................................................................. 41

3.15.

SYCL アプリケーションの例........................................................................................................................................................................................ 41

第 4 章 SYCL プログラミング・インターフェイス ........................................................................................................................................................................ 44
4.1. バックエンド .................................................................................................................................................................................................................................. 44
4.1.1. バックエンド・マクロ ........................................................................................................................................................................................................ 44
4.2. ジェネリック vs 非ジェネリック SYCL ............................................................................................................................................................................... 44
4.3. ヘッダーファイルと名前空間 ................................................................................................................................................................................................. 45
4.4. 利用可能なクラス ....................................................................................................................................................................................................................... 45
4.5. 共通インターフェイス ................................................................................................................................................................................................................ 45
4.5.1. バックエンドの相互運用性 .......................................................................................................................................................................................... 46
4.5.1.1. タイプ特性 backend_traits............................................................................................................................................................................... 46
4.5.1.2. テンプレート関数 get_native .......................................................................................................................................................................... 47
4.5.1.3. テンプレート関数 make_* ................................................................................................................................................................................. 47
4.5.2. 共通参照セマンティクス................................................................................................................................................................................................ 49
4.5.3. 共通値渡しセマンティクス ........................................................................................................................................................................................... 51
4.5.4. プロパティー ........................................................................................................................................................................................................................ 53
4.5.4.1. プロパティー・インターフェイス ........................................................................................................................................................................ 54
4.6. SYCL ランタイムクラス ........................................................................................................................................................................................................... 55
4.6.1. デバイスの選択 .................................................................................................................................................................................................................. 55
4.6.1.1. デバイスセレクター ................................................................................................................................................................................................ 56
4.6.2. プラットフォーム・クラス ................................................................................................................................................................................................ 59

3 | 目次SYCL 2020 リビジョン 6
4.6.2.1. プラットフォーム・インターフェイス ................................................................................................................................................................ 59
4.6.2.2. プラットフォーム情報記述子 ............................................................................................................................................................................ 61
4.6.3. コンテキスト・クラス ........................................................................................................................................................................................................ 61
4.6.3.1. コンテキスト・インターフェイス ........................................................................................................................................................................ 62
4.6.3.2. コンテキスト情報記述子 ..................................................................................................................................................................................... 64
4.6.3.3. コンテキスト・プロパティー ................................................................................................................................................................................ 65
4.6.4. デバイスクラス ................................................................................................................................................................................................................... 65
4.6.4.1. デバイス・インターフェイス ................................................................................................................................................................................. 65
4.6.4.2. デバイス情報記述子 .............................................................................................................................................................................................. 70
4.6.4.3. デバイスアスペクト ................................................................................................................................................................................................ 81
4.6.5. キュークラス ........................................................................................................................................................................................................................ 85
4.6.5.1. キュー・インターフェイス ...................................................................................................................................................................................... 85
4.6.5.2. キュー・ショートカット関数................................................................................................................................................................................. 92
4.6.5.3. キュー情報記述子 ................................................................................................................................................................................................... 97
4.6.5.4. キュー・プロパティー .............................................................................................................................................................................................. 97
4.6.5.5. キューエラー処理 ................................................................................................................................................................................................... 98
4.6.6. イベントクラス .................................................................................................................................................................................................................... 98
4.6.6.1. イベント情報とプロファイル記述子 ............................................................................................................................................................ 101
4.7. SYCL のデータアクセスとストレージ............................................................................................................................................................................. 102
4.7.1. ホスト割り当て ................................................................................................................................................................................................................ 103
4.7.1.1. デフォルト・アロケーター .................................................................................................................................................................................. 103
4.7.2. バッファー .......................................................................................................................................................................................................................... 104
4.7.2.1. バッファー・インターフェイス .......................................................................................................................................................................... 104
4.7.2.2. バッファー・プロパティー .................................................................................................................................................................................. 116
4.7.2.3. バッファー同期規則 ............................................................................................................................................................................................ 117
4.7.3. イメージ .............................................................................................................................................................................................................................. 119
4.7.3.1. 非サンプル・イメージ・インターフェイス .................................................................................................................................................... 120
4.7.3.2. サンプル・イメージ・インターフェイス ......................................................................................................................................................... 128
4.7.3.3. イメージ・プロパティー ...................................................................................................................................................................................... 132
4.7.3.4. イメージ同期規則 ................................................................................................................................................................................................ 133
4.7.4. SYCL データ管理クラスとホストメモリーの共有 .......................................................................................................................................... 134
4.7.4.1. デフォルトの動作 ................................................................................................................................................................................................. 134
4.7.4.2. ホストメモリーの SYCL 所有権 .................................................................................................................................................................... 134
4.7.4.3. ホストメモリーの共有 SYCL 所有権 .......................................................................................................................................................... 135
4.7.5. 同期プリミティブ............................................................................................................................................................................................................ 135
4.7.6. アクセサー ......................................................................................................................................................................................................................... 136
4.7.6.1. データタイプ ........................................................................................................................................................................................................... 136
4.7.6.2. アクセスモード ...................................................................................................................................................................................................... 137
4.7.6.3. デダクション・タグ ................................................................................................................................................................................................ 138

4 | 目次SYCL 2020 リビジョン 6
4.7.6.4. プロパティー ........................................................................................................................................................................................................... 138
4.7.6.5. 読み取り専用アクセサー .................................................................................................................................................................................. 140
4.7.6.6. アクセサーの要素をアクセス ......................................................................................................................................................................... 140
4.7.6.7. コンテナーのインターフェイス ...................................................................................................................................................................... 140
4.7.6.8. レンジ付きアクセサー ....................................................................................................................................................................................... 141
4.7.6.9. コマンドのバッファーアクセサー ................................................................................................................................................................. 141
4.7.6.9.1. バッファー・コマンド・アクセサーのインターフェイス ............................................................................................................... 142
4.7.6.9.2. バッファー・コマンド・アクセサーのデダクション・タグ ............................................................................................................ 150
4.7.6.9.3. 読み取り専用バッファー・コマンド・アクセサーと暗黙の変換 .............................................................................................. 150
4.7.6.9.4. accessor クラスの非推奨の機能 ....................................................................................................................................................... 151
4.7.6.10.

ホストコードのバッファーアクセサー .............................................................................................................................................. 164

4.7.6.10.1.バッファー・ホスト・アクセサーのインターフェイス .................................................................................................................... 164
4.7.6.10.2.バッファー・コマンド・アクセサーのデダクション・タグ ............................................................................................................ 168
4.7.6.10.3.読み取り専用バッファー・ホスト・アクセサーと暗黙の変換 ................................................................................................... 169
4.7.6.11.

ローカルアクセサー.................................................................................................................................................................................. 169

4.7.6.11.1.ローカルアクセサーのインターフェイス ......................................................................................................................................... 170
4.7.6.11.2.読み取り専用ローカルアクセサーと暗黙の変換........................................................................................................................ 173
4.7.6.12.

バッファーとローカルアクセサーの共通メンバー ..................................................................................................................... 173

4.7.6.13.

非サンプルイメージのアクセサー ..................................................................................................................................................... 177

4.7.6.13.1.非サンプルイメージのアクセサー・インターフェイス ............................................................................................................... 178
4.7.6.13.2.非サンプル・イメージ・アクセサーのデダクション・タグ ........................................................................................................... 181
4.7.6.13.3.読み取り専用非サンプル・イメージ・アクセサーと暗黙の変換 ............................................................................................ 182
4.7.6.14.

サンプル・イメージ・アクセサー ........................................................................................................................................................... 182

4.7.6.14.1.サンプル・イメージ・アクセサーのインターフェイス ................................................................................................................... 182
4.7.6.14.2.サンプル・イメージ・アクセサーのデダクション・タグ ................................................................................................................ 185
4.7.6.14.3.読み取り専用サンプル・イメージ・アクセサーと暗黙の変換 ................................................................................................. 186
4.7.7. アドレス空間クラス ....................................................................................................................................................................................................... 186
4.7.7.1. 複数ポインタークラス ........................................................................................................................................................................................ 186
4.7.7.2. 明示的なポインターエイリアス ..................................................................................................................................................................... 202
4.7.8. イメージサンプラー ...................................................................................................................................................................................................... 203
4.8. 統合共有メモリー (USM) ..................................................................................................................................................................................................... 204
4.8.1. 統合アドレス指定 .......................................................................................................................................................................................................... 206
4.8.2. 統合共有メモリーの種類............................................................................................................................................................................................ 206
4.8.3. USM 割り当て .................................................................................................................................................................................................................. 208
4.8.3.1. C++ アロケーター・インターフェイス.......................................................................................................................................................... 209
4.8.3.2. デバイス割り当て関数 ....................................................................................................................................................................................... 211
4.8.3.3. ホスト割り当て関数 ............................................................................................................................................................................................ 212
4.8.3.4. 共有割り当て関数 ................................................................................................................................................................................................ 213
4.8.3.5. パラメーター化された割り当て関数 .......................................................................................................................................................... 215

5 | 目次SYCL 2020 リビジョン 6
4.8.3.6. メモリー割り当て解除関数 ............................................................................................................................................................................. 216
4.8.4. 統合共有メモリーポインター照会 ......................................................................................................................................................................... 217
4.9. カーネルを介して並列処理を表現................................................................................................................................................................................... 217
4.9.1. レンジとインデックス空間識別子 .......................................................................................................................................................................... 217
4.9.1.1. range クラス........................................................................................................................................................................................................... 218
4.9.1.2. nd_range class .................................................................................................................................................................................................... 221
4.9.1.3. id クラス ................................................................................................................................................................................................................... 222
4.9.1.4. item クラス ............................................................................................................................................................................................................. 225
4.9.1.5. nd_item クラス ..................................................................................................................................................................................................... 227
4.9.1.6. h_item クラス ........................................................................................................................................................................................................ 230
4.9.1.7. group クラス .......................................................................................................................................................................................................... 233
4.9.1.8. sub_group クラス ............................................................................................................................................................................................... 238
4.9.2. リダクション変数............................................................................................................................................................................................................ 239
4.9.2.1. reduction インターフェイス ........................................................................................................................................................................... 242
4.9.2.2. リダクション・プロパティー .............................................................................................................................................................................. 244
4.9.2.3. reducer クラス ...................................................................................................................................................................................................... 244
4.9.3. コマンドグループのスコープ ................................................................................................................................................................................... 247
4.9.4. コマンドグループ handler クラス ........................................................................................................................................................................ 248
4.9.4.1. 要件を追加する SYCL 関数 ............................................................................................................................................................................ 251
4.9.4.2. カーネルを呼び出す SYCL 関数 ................................................................................................................................................................... 252
4.9.4.2.1. single_task 呼び出し............................................................................................................................................................................... 255
4.9.4.2.2. parallel_for 呼び出し .............................................................................................................................................................................. 256
4.9.4.2.3. 階層的な呼び出しの並列処理 ............................................................................................................................................................. 260
4.9.4.3. 明示的なメモリー操作を行う SYCL 関数 ................................................................................................................................................ 263
4.9.4.4. カーネルバンドルを使用する関数 ............................................................................................................................................................... 267
4.9.5. 特殊化定数........................................................................................................................................................................................................................ 267
4.9.5.1. 特殊化定数の宣言 ............................................................................................................................................................................................... 268
4.9.5.1.1. コンストラクター ........................................................................................................................................................................................ 269
4.9.5.1.2. 特殊メンバー関数 ..................................................................................................................................................................................... 269
4.9.5.2. 特殊化定数値の設定と取得 ............................................................................................................................................................................ 270
4.9.5.3. デバイスコードから特殊化定数値を読み取る ....................................................................................................................................... 270
4.9.5.3.1. メンバー関数 ............................................................................................................................................................................................... 271
4.9.5.4. 使用例........................................................................................................................................................................................................................ 271
4.10.

ホストタスク ..................................................................................................................................................................................................................... 272

4.10.1.

概要............................................................................................................................................................................................................................. 272

4.10.2.

クラス interop_handle .................................................................................................................................................................................... 274

6 | 目次4.10.2.1.

コンストラクター ........................................................................................................................................................................................ 274

4.10.2.2.

メンバー関数 ............................................................................................................................................................................................... 274

4.10.2.3.

テンプレート・メンバー関数 get_native_* .................................................................................................................................... 274

SYCL 2020 リビジョン 6
4.10.3.
4.11.

handler クラスへの追加................................................................................................................................................................................... 276

カーネルバンドル .......................................................................................................................................................................................................... 277

4.11.1.

概要............................................................................................................................................................................................................................. 277

4.11.2.

概要............................................................................................................................................................................................................................. 278

4.11.3.

固定機能のビルトインカーネル .................................................................................................................................................................... 280

4.11.4.

バンドルの状態 ..................................................................................................................................................................................................... 280

4.11.5.

カーネル識別子 .................................................................................................................................................................................................... 281

4.11.6.

カーネル識別子を取得する ............................................................................................................................................................................. 282

4.11.7.

カーネルバンドルを取得する ......................................................................................................................................................................... 282

4.11.8.

カーネルバンドルの存在を照会する .......................................................................................................................................................... 285

4.11.9.

カーネルがデバイスと互換性があるか照会する .................................................................................................................................. 286

4.11.10.

カーネルバンドルに参加する ........................................................................................................................................................................ 286

4.11.11.

オンラインコンパイルとリンク ...................................................................................................................................................................... 287

4.11.12.

kernel_bundle クラス ...................................................................................................................................................................................... 289

4.11.12.1.

照会................................................................................................................................................................................................................... 290

4.11.12.2.

特殊化定数のサポート ............................................................................................................................................................................ 292

4.11.12.3.

デバイスイメージのサポート ................................................................................................................................................................ 292

4.11.13.

kernel クラス ......................................................................................................................................................................................................... 293

4.11.13.1.

照会................................................................................................................................................................................................................... 293

4.11.13.2.

カーネル情報記述子 ................................................................................................................................................................................ 294

4.11.14.

device_image クラス ........................................................................................................................................................................................ 296

4.11.15.

使用例........................................................................................................................................................................................................................ 296

4.11.15.1.

オンラインコンパイルのタイミングを制御 ................................................................................................................................... 296

4.11.15.2.

特殊化定数.................................................................................................................................................................................................... 297

4.11.15.3.

カーネルの内容調査 ................................................................................................................................................................................. 298

4.11.15.4.

デバイス・ビルトイン・カーネルの呼び出し .................................................................................................................................... 299

4.12.

カーネルの定義 ............................................................................................................................................................................................................... 299

4.12.1.

名前付き関数オブジェクトとしてカーネルを定義 ............................................................................................................................... 300

4.12.2.

ラムダ関数としてカーネルを定義 ............................................................................................................................................................... 300

4.12.3.

is_device_copyable タイプ特性 ................................................................................................................................................................. 302

4.12.4.

カーネルへパラメーターを渡す規則 .......................................................................................................................................................... 303

4.13.

エラー処理 ........................................................................................................................................................................................................................ 304

4.13.1.

エラー処理規則 .................................................................................................................................................................................................... 304

4.13.1.1.

非同期例外ハンドラー ............................................................................................................................................................................ 304

4.13.1.2.

async_handler なしの動作 .................................................................................................................................................................. 304

4.13.1.3.

async_handler の優先順位 ................................................................................................................................................................. 304

4.13.1.4.

セカンダリー・キューでの非同期エラー .......................................................................................................................................... 305

4.13.2.
4.14.

例外クラス・インターフェイス ......................................................................................................................................................................... 306

データタイプ ..................................................................................................................................................................................................................... 311

7 | 目次SYCL 2020 リビジョン 6
4.14.1.

スカラー・データ・タイプ..................................................................................................................................................................................... 311

4.14.2.

ベクトルタイプ....................................................................................................................................................................................................... 311

4.14.2.1.

Vec インターフェイス ............................................................................................................................................................................... 312

4.14.2.2.

エイリアス ...................................................................................................................................................................................................... 327

4.14.2.3.

スウィズル ...................................................................................................................................................................................................... 327

4.14.2.4.

スウィズル vec クラス .............................................................................................................................................................................. 328

4.14.2.5.

丸めモード ..................................................................................................................................................................................................... 328

4.14.2.6.

メモリー配置とアライメント................................................................................................................................................................. 328

4.14.2.7.

パフォーマンスの注意点 ........................................................................................................................................................................ 329

4.14.3.

数学配列タイプ ..................................................................................................................................................................................................... 329

4.14.3.1.

数学配列インターフェイス ..................................................................................................................................................................... 329

4.14.3.2.

エイリアス ...................................................................................................................................................................................................... 338

4.14.3.3.

メモリー配置とアライメント................................................................................................................................................................. 338

4.15.

同期とアトミック ............................................................................................................................................................................................................ 338

4.15.1.

バリアとフェンス................................................................................................................................................................................................... 338

4.15.2.

device_event クラス ......................................................................................................................................................................................... 339

4.15.3.

アトミック参照 ...................................................................................................................................................................................................... 340

4.15.4.

アトミックタイプ (非推奨) ............................................................................................................................................................................... 349

4.16.

ストリームクラス ............................................................................................................................................................................................................ 356

4.16.1.

ストリーム・クラス・インターフェイス ........................................................................................................................................................... 357

4.16.2.

同期............................................................................................................................................................................................................................. 360

4.16.3.

暗黙のフラッシュ ................................................................................................................................................................................................. 360

4.16.4.

パフォーマンスの注意点 .................................................................................................................................................................................. 361

4.17.

SYCL ホストとデバイス向けの SYCL ビルトイン関数 ................................................................................................................................ 361

4.17.1.

SYCL ホストおよびデバイスで利用可能なビルトインタイプの説明 .......................................................................................... 361

4.17.2.

関数オブジェクト .................................................................................................................................................................................................. 364

4.17.3.

グループ関数 ......................................................................................................................................................................................................... 366

4.17.3.1.

グループタイプの特性 ............................................................................................................................................................................. 366

4.17.3.2.

group_broadcast ..................................................................................................................................................................................... 367

4.17.3.3.

group_barrier ............................................................................................................................................................................................. 367

4.17.4.

グループ・アルゴリズム・ライブラリー ........................................................................................................................................................ 368

4.17.4.1.

any_of、all_of および none_of .......................................................................................................................................................... 369

4.17.4.2.

shift_left と shift_right .......................................................................................................................................................................... 370

4.17.4.3.

permute ......................................................................................................................................................................................................... 371

4.17.4.4.

select ............................................................................................................................................................................................................... 371

4.17.4.5.

reduce............................................................................................................................................................................................................. 371

4.17.4.6.

exclusive_scan と inclusive_scan ................................................................................................................................................... 373

4.17.5.

数学関数................................................................................................................................................................................................................... 375

4.17.6.

整数関数................................................................................................................................................................................................................... 380

8 | 目次SYCL 2020 リビジョン 6
4.17.7.

共通関数................................................................................................................................................................................................................... 382

4.17.8.

ジオメトリー関数 ................................................................................................................................................................................................. 383

4.17.9.

リレーショナル関数............................................................................................................................................................................................. 385

第 5 章 SYCL デバイス・コンパイラー ............................................................................................................................................................................................ 388
5.1. SYCL ソースファイルのオフラインコンパイル .......................................................................................................................................................... 388
5.2. カーネルの命名 ......................................................................................................................................................................................................................... 388
5.3. 関数のコンパイル .................................................................................................................................................................................................................... 389
5.4. デバイス関数の言語制限 ..................................................................................................................................................................................................... 389
5.5. ビルトインのスカラー・データ・タイプ ............................................................................................................................................................................. 390
5.6. プリプロセッサー・ディレクティブとマクロ .................................................................................................................................................................. 391
5.7. オプションのカーネル機能 .................................................................................................................................................................................................. 392
5.8. デバイスコードの属性............................................................................................................................................................................................................ 393
5.8.1. カーネル属性 ................................................................................................................................................................................................................... 393
5.8.2. デバイス関数属性 .......................................................................................................................................................................................................... 397
5.9. アドレス空間の推定 ................................................................................................................................................................................................................ 398
5.9.1. アドレス空間の割り当て ............................................................................................................................................................................................. 399
5.9.2. 共通アドレス空間の推定規則 .................................................................................................................................................................................. 399
5.9.3. デフォルトアドレス空間としての汎用性 ............................................................................................................................................................. 399
5.9.4. 推定アドレス空間 .......................................................................................................................................................................................................... 400
5.10.

SYCL オフラインリンク ............................................................................................................................................................................................... 400

5.10.1.

SYCL 関数とメンバー関数のリンク............................................................................................................................................................ 400

第 6 章 SYCL 拡張 .................................................................................................................................................................................................................................. 402
6.1. 拡張機能の定義 ........................................................................................................................................................................................................................ 402
6.2. 拡張機能の要件 ........................................................................................................................................................................................................................ 402
6.3. ポータブルな拡張のガイドライン .................................................................................................................................................................................... 403
6.3.1. 拡張名前空間................................................................................................................................................................................................................... 403
6.3.2. 既存のクラスまたは列挙の拡張名 ........................................................................................................................................................................ 403
6.3.3. 機能を評価するマクロ ................................................................................................................................................................................................. 403
6.3.4. 属性名前空間................................................................................................................................................................................................................... 404
6.3.5. インクルード・ファイル・パス ...................................................................................................................................................................................... 404
6.3.6. オプションのカーネル機能 ........................................................................................................................................................................................ 404
6.3.7. バックエンドの追加 ...................................................................................................................................................................................................... 404
付録 A 情報記述子 .................................................................................................................................................................................................................................. 405
A.1. プラットフォーム情報記述子 ............................................................................................................................................................................................. 405
A.2. コンテキスト情報記述子 ...................................................................................................................................................................................................... 405
A.3. デバイス情報記述子 ............................................................................................................................................................................................................... 405
A.4. キュー情報記述子 .................................................................................................................................................................................................................... 408
A.5. カーネル情報記述子 .............................................................................................................................................................................................................. 409
A.6. イベント情報記述子................................................................................................................................................................................................................ 409

9 | 目次SYCL 2020 リビジョン 6
付録 B 機能セット.................................................................................................................................................................................................................................... 411
B.1. 完全な機能セット..................................................................................................................................................................................................................... 411
B.2. 縮小された機能セット ........................................................................................................................................................................................................... 411
B.3. 互換性 ............................................................................................................................................................................................................................................ 411
B.4. 適合性 ............................................................................................................................................................................................................................................ 411
付録 C OpenCL バックエンド仕様 ................................................................................................................................................................................................. 412
C.1. SYCL アプリケーションとネイティブ・バックエンド・オブジェクトの相互運用性 ...................................................................................... 412
C.2. カーネル関数とネイティブ・バックエンド・オブジェクトの相互運用性 ........................................................................................................... 412
C.3. 参照セマンティクスによる相互運用構造オブジェクトの破棄 ........................................................................................................................... 413
C.4. OpenCL フレームワーク向けの SYCL .......................................................................................................................................................................... 414
C.5. OpenCL 上での SYCL プログラミング・モデルの対応 ......................................................................................................................................... 414
C.5.1. バックエンド固有の情報記述子 ............................................................................................................................................................................. 415
C.5.2. OpenCL メモリーモデル............................................................................................................................................................................................ 415
C.5.3. バッファー・コマンド・アクセサーの OpenCL インターフェイス .............................................................................................................. 415
C.5.4. SYCL アプリケーションによる OpenCL リソース管理............................................................................................................................... 416
C.6. OpenCL API との相互運用性 ............................................................................................................................................................................................ 416
C.7. プログラミング・インターフェイス ................................................................................................................................................................................... 418
C.7.1. OpenCL オブジェクトから SYCL オブジェクトを構築 ................................................................................................................................ 418
C.7.2. 拡張クエリー .................................................................................................................................................................................................................... 421
C.7.3. 参照カウント .................................................................................................................................................................................................................... 421
C.7.4. エラーと制限 .................................................................................................................................................................................................................... 421
C.7.5. カーネルバンドルとの相互運用性 ........................................................................................................................................................................ 421
C.7.6. カーネルとの相互運用性 ........................................................................................................................................................................................... 422
C.7.7. OpenCL カーネル規約と SYCL.............................................................................................................................................................................. 423
C.7.8. データタイプ ..................................................................................................................................................................................................................... 424
C.8. プリプロセッサー・ディレクティブとマクロ .................................................................................................................................................................. 425
C.8.1. OpenCL C ライブラリーとのオフラインリンク ............................................................................................................................................... 425
C.9. 非コア OpenCL 機能のサポート ..................................................................................................................................................................................... 425
C.9.1. 半精度浮動小数点......................................................................................................................................................................................................... 426
C.9.2. 3D イメージ・メモリー・オブジェクトへの書き込み ........................................................................................................................................ 426
C.9.3. OpenGL との相互運用性 .......................................................................................................................................................................................... 426
C.10.

OpenCL 機能の SYCL への対応 ............................................................................................................................................................................ 426

C.10.1.

Work-item 関数................................................................................................................................................................................................... 427

C.10.2.

ベクトルデータのロードとストア関数........................................................................................................................................................ 427

C.10.3.

同期関数................................................................................................................................................................................................................... 427

C.10.4.

printf 関数 ............................................................................................................................................................................................................... 427

付録 D 前バージョンからの変更点 ................................................................................................................................................................................................. 428
D.1. SYCL 1.2.1 から SYCL 2020 への変更点................................................................................................................................................................... 428
付録 E 参考資料 ....................................................................................................................................................................................................................................... 434

10 | 目次SYCL 2020 リビジョン 6
用語集 ............................................................................................................................................................................................................................................................ 435

11 | 目次SYCL 2020 リビジョン 6

Copyright (c) 2011-2022 The Khronos Group, Inc.
この仕様は著作権法によって保護されており、Khronos が所有するマテリアルが含まれています。これらの条件に記載される場合を除き、Khronos の書面による事前の明示的な許可なしに、コンポーネントまたはコンポーネントの複製、再発行、配布、送信、表示、放送、
またはその他の方法で利用することはできません。Khronos は、変更されていない仕様を任意の目的で利用および複製するため条件付き著作権ラインセンスを、これらの条件に基づいて特許、商標、またはその他の知的財産権のライセンスが付与されない場合を除き、料金またはロイヤルティーなしで付与します。
Khronos は、本仕様に関して、明示または暗黙を問わず、以下を含みますがこれらに限定されない表明または保証を行うことなく、明示的に否認します: 商品性、特定の目的への適合性、知的財産の非侵害、正当性、正確性、完全性、適時性、および信頼性。いかなる状況においても、Khronos またはそのプロモーター、寄稿者、メンバー、またはそれぞれのパートナー、役員、取締役、従業員、または代表者
は、直接的、間接的、特殊な、または結果として生じた利益の損失、これらのマテリアルに起因または関連して生じた利益の損失、またはその他の方法にかかわらず、いかなる損害についても責任を負いません。
この仕様は、https://www.khronos.org/files/ member_agreement.pdf (英語) で入手可能な Khronos Group メンバーシップ契約の添付資料 A であり、「スコープ」、「準拠部分」、「必要な特許クレーム」という用語を定義する Khronos 知的財産権ポリシーに基づいて作成されています。仕様を実装し、その実装に関連して Khronos の商標を利用し、Khronos の知的財産権ポリシーに基づいて相互特許ライセンス保護を受けることを希望する当事者は、採用者となり、この仕様について Khronos が定義したプロセスに準拠していることを確認する必要があります。https://www.khronos.org/adopters (英語) を参照してください。
この仕様の一部は純粋に参考情報であるため、この仕様の範囲から除外されます。
この仕様が用語集などで定義されている、仕様に明記されていないイネーブリング・テクノロジーを示す技術用語を使用している場合、それらのイネーブリング・テクノロジーは、この仕様の範囲から除外されます。明確にするため、この仕様で具体的に開示されていない技術を可能にする (例えば、半導体製造技術、ハードウェア・アーキテクチャー、プロセッサー・アーキテクチャー、またはマイクロアーキ
テクチャー、メモリー・アーキテクチャー、コンパイラー技術、オブジェクト指向技術、基本的なオペレーティング・システム技術、圧縮技
術、アルゴリズムなど) 明示的に記載されているとは見なされるべきではありません。この仕様の範囲には、特定の方法で開示されたア
プリケーションのプログラミング・インターフェイスとデータ構造のみが含まれます。
必要な特許請求の範囲の定義に関連する Khronos の知的財産権ポリシーの目的上、この仕様に記載されるすべての推奨またはオプションの特徴、動作、および機能は、実装されている場合、準拠する部分として含まれると見なされます。
この仕様に外部文書の基準となる参照が含まれている場合、それらの外部文書の具体的に特定されたセクションのみがこの仕様の範囲に含まれます。Khronos によって作成されたものではない場合、それらの外部文書には、Khronos の知的財産権ポリシーの対象外のKhronos の非会員からの寄稿が含まれている場合があります。
このドキュメントには、Khronos によって承認されていない拡張機能が含まれており、承認された SYCL 仕様からのテキスト (およびその ス ー パ ー セ ッ ト ) が 含 ま れ ま す が 、 承 認 さ れ た 仕 様 で は あ り ま せ ん 。 SYCL 仕 様 の 承 認 済 み バ ー ジ ョ ン は 、
https://www.khronos.org/registry/SYCL (英語) にあります。
Khronos および Vulkan は登録商標であり、SPIR-V は Khronos Group Inc の商標です。OpenCL は Apple Inc の商標で、OpenGL は
Hewlett Packard Enterprise の登録商標であり、すべて Khronos のライセンスに基づいて使用されています。他のすべての製品名、商標、および/または会社名は、識別のためにのみ使用され、それぞれの所有者に帰属します。

12 | 序文

SYCL 2020 リビジョン 6

第 1 章 謝辞
編集者
• Maria Rovatsou, Codeplay• Lee Howes, Qualcomm• Ronan Keryell, AMD (現職)
共著者
• Eric Berdahl, Adobe• Shivani Gupta, Adobe• David Neto, Altera• Carlo Bertolli, AMD• Andrew Gozillon, AMD• Gauthier Harnisch, AMD• Ronan Keryell, AMD• Yiannis Papadopoulos, AMD• Brian Sumner, AMD• Lin-Ya Yu, AMD• Thomas Applencourt, Argonne National Laboratory• Hal Finkel, Argonne National Laboratory• Kevin Harms, Argonne National Laboratory• Nevin Liber, Argonne National Laboratory• Anastasia Stulova, ARM• Balázs Keszthelyi, Broadcom• Alexandra Crabb, Caster Communications• Stuart Adams, Codeplay• Verena Beckham, Codeplay• Aidan Belton, Codeplay• Gordon Brown, Codeplay• Morris Hafner, Codeplay• Alexander Johnston, Codeplay• Marios Katsigiannis, Codeplay• Paul Keir, Codeplay• Steffen Larsen, Codeplay• Victor Lomüller, Codeplay• Tomas Matheson, Codeplay• Duncan McBain, Codeplay• Nicolas Miller, Codeplay• Ralph Potter, Codeplay• Ruyman Reyes, Codeplay• Andrew Richards, Codeplay• Maria Rovatsou, Codeplay• Panagiotis Stratis, Codeplay• Michael Wong, Codeplay• Peter Žužek, Codeplay• Matt Newport, EA• Rasool Maghareh, Huawei Technologies Co. Ltd.

第 1 章 謝辞 | 13

SYCL 2020 リビジョン 6• Guansong Zhang, Huawei Technologies Co. Ltd.
• Ruslan Arutyunyan, Intel• Alexey Bader, Intel• James Brodman, Intel• Ilya Burylov, Intel• Jessica Davies, Intel• Felipe de Azevedo Piovezan, Intel• Allen Hux, Intel• Michael Kinsner, Intel• Greg Lueck, Intel• John Pennycook, Intel• Roland Schulz, Intel• Sergey Semenov, Intel• Jason Sewall, Intel• James O’Riordon, Khronos• Jon Leech, Luna Princeps LLC• Kathleen Mattson, Miller & Mattson, LLC• Dave Miller, Miller & Mattson, LLC• Stéphanie Even, Mercedes-Benz Research and Development NA• Chris Gearing, Mobileye• Seiji Nishimura, NSITEXE, Inc.
• Neil Trevett, NVIDIA• Lee Howes, Qualcomm• Chu-Cheow Lim, Qualcomm• Jack Liu, Qualcomm• Hongqiang Wang, Qualcomm• Ruihao Zhang, Qualcomm• Dave Airlie, Red Hat• Hyesun Hong, Samsung Electronics• Aksel Alpay, Self
• Dániel Berényi, Self
• Máté Nagy-Egri, Stream HPC• Bálint Soproni, Stream HPC• Tom Deakin, University of Bristol• Philip Salzmann, University of Innsbruck• Peter Thoman, University of Innsbruck• Biagio Cosenza, University of Salerno• Paul Preney, University of Windsor

第 1 章 謝辞 | 14

SYCL 2020 リビジョン 6

第 2 章 はじめに
SYCL (“シクル” と読みます) は、異種コンピューティング向けのロイヤルティー・フリーのクロスプラットフォーム抽象化 C++ プログラ
ミング・モデルです。ＳＹＣＬ は、並列 API または OpenCL などの標準化された基本的な概念、移植性、効率性に基づいて構築されており、単一ソース C++ の使い易さと柔軟性の多くが追加されています。
ＳＹＣＬ を利用する開発者は、継承やテンプレートなど、慣れ親しんだ多くの手法を使用して、標準の現代化された C++ コードを記述できます。同時に、開発者は、ＳＹＣＬ ライブラリーの機能と、必要に応じて、ＡＰＩ を使用して、基盤となる実装を直接使用して記述されたコードとの相互運用の両方を通じて、実装 (OpenCL など) のすべての機能にアクセスできます。
プログラミングの労力を軽減し、開発者がコードを記述する柔軟性を高めるため、ＳＹＣＬ は OpenCL モデルなどの標準化に見られる概念を、C++ 機能の一般的な用途を超えた方法によって拡張します。

• 異種デバイスで並列カーネルの実行は、同時性があり、利便性があり、さらに柔軟性があります。一般的な並列パターンは単純な構文が優先されます。これにより、一連の C++ タイプを通して、プログラマーは必要に応じて同期などの追加要件を表現できます。

• バッファーとアクセサーを使用することで、ＳＹＣＬ のデータアクセスはデータストレージから分離されます。C++ スタイルのリソー
ス取得は初期化 (RAII) イディオムに依存し、デバイスのコードブロック間のデータ依存関係をキャプチャーすることでランタイム・ライブラリーはデータ移動を追跡して、カーネル・インスタンス間の複雑なイベント依存関係を手動で管理することなく正しい動作をもたらします。プログラマーは明示的にデータを移動する必要があります。このアプローチにより、すでに実行モデルの一部である可能性があるデータ並列タスクグラフを SYCL プログラマーは容易にかつ安全に構築できます。

• 統合共有メモリー (USM) は、明示的なデータの割り当てと移動のメカニズムを提供します。このアプローチでは、異種デバイス間
でポインターベースのアルゴリズムとデータ構造の使用が可能となり、ホストとデバイス間でコードの再利用が可能になります。

• 階層並列構文は、OpenCL デバイスまたは OpenMP ターゲットデバイス実行モデルと同様のデータ並列性を、理解しやすい現代の C++ 形式で表現することを可能にします。コードの断片化を回避して CPU スタイルのアーキテクチャーに効率良くマッピン
グするため、並列ループと同期ポイントをよりクリーンに階層化します。
SYCL は、OpenCL 標準から派生した実行モデル、ランタイム機能セット、およびデバイス機能を持っています。この標準化は、SYCL がサポートする C++ 機能のすべての範囲にいくつかの制限を課しています。これにより、可能な限り広範囲のデバイス間でデバイスコー
ドを移植できるようになります。その結果、コードは標準の C++ プログラムと相互運用性を備えた C++ 構文を記述できますが、SYCL
デバイスコードでは C++ 機能セット全体を利用することはできません。特に、この仕様で定義される SYCL デバイスコードは、仮想関数呼び出し、一般的なポインター、例外、ランタイム型の情報、またはこれらの機能や特定のホスト・コンパイラーの機能に依存する可能性がある C++ ライブラリーの完全な機能をサポートしていません。しかし、これらの基本的な制限は、Khronos またはベンダーの特定の拡張機能により緩和することができます。
SYCL は、ツールチェーンの柔軟性を維持しながら、ソース統合を支援する SMCP 設計を実装しています。SMCP の設計は、ホストコー
ドにインライン展開される GPU などデバイス向けにコンパイルすることを目的としたコードの埋め込みをサポートします。このコードの埋め込みには、次のような利点があります。

簡素性
OpenCL などのフレームワークを利用するプログラマーにとって、OpenCL でホストとデバイスのソースコードを分離する作業は、特に同様のカーネルコードが異なるデータタイプで複雑な異なるワークで使用される場合、処理が複雑になる可能性があります。単一のコ
ンパイルフローと、多数の単純なタスクを実行するライブラリーを組み合わせた統合ツールチェーンにより、初期の OpenCL プログラ
ムの複雑性を最小化します。これにより、異種プログラミングに慣れていないプログラマーの習得時間が短縮され、構文そのものではなく並列化の手法に集中できるようになります。

第 2 章 はじめに | 15

SYCL 2020 リビジョン 6

再利用
C++ の型システムは、異なるコードユニット間の複雑な相互作用を可能にし、効率良い抽象化インターフェイスの設計とライブラリー・
コードの再利用をサポートします。例えば、データ配列に適用される変換やマップ操作により、配列の各要素に適用される操作とデータタイプの両方に特化できることがあります。ＳＹＣＬ の SMCP 設計の相互作用によってホストコードとデバイスコードの境界を橋渡しして、デバイスコードをホストコードから直接両方の要素に特殊化できます。

効率
タイプシステムと密接に統合し、ライブラリーを再利用することで、コンパイラーはコードのインライン展開を行い、カーネルソース文
字列を動的に変更することなく、ホストコードで決定された専用デバイスコードを効率良く生成できます。
既存の異種実行モデルに加えて、ジェネリック・プログラミング、テンプレート・コード、関数型プログラミング、継承など C++ の機能を利用することで、異種システムのソフトウェア設計において革新的で広範囲な選択が可能になります。単一の C++ 型システム内でデバイスとホストコードを統合することで、シンプルでありながら効率良いインターフェイスを構築する、現代的で、テンプレート化された
ジェネリックおよび適用可能なライブラリーの開発が可能となり、多くの開発者が異種コンピューティングの機能とデバイスにアクセスできるようになります。SYCL は、OpenCL や Vulkan などオープンで広く実装されている標準化された基盤上に構築された異種シス
テムのプログラミング・モデルにおけるイノベーションの基盤として機能することを目的としています。
SYCL は、標準の C++ に可能な限り近づけるように設計されています。実際には、SYCL と基盤となる実装との統合に依存しない限り、
標準 C++ コンパイラーは SYCL プログラムをコンパイルでき、ホスト CPU で正しく実行できることを意味します。特殊な低レベルの機能を使用する場合、コンパイラー固有の組込み関数を隠匿して異なるホスト・コンパイラー間の移植性を維持するのと同じ方法で、C プ
リプロセッサーによりマスクできます。
SYCL は、開発者が使用する標準 C++ ホスト・コンパイラーを含む異なる複数のコンパイラーによってソースファイルが処理され、アプ
リケーションがこれらのコンパイルパスの結果を組み合わせるコンパイルフローを可能にするように設計されています。これは、標準のホスト・コンパイラーの利用を妨げる言語拡張を使用する可能性がある単一ソースフローとは根本的に異なります。SYCL 標準は、単一のコンパイルフローを排除するものではありませんが、それを必要としないように設計されています。ＳＹＣＬ は、純粋にライブラリー
として実装することもできます。その場合、コンパイラーによる特別なサポートは必要ありません。
この設計には 2 つの利点があります。最初に、既存のツールチェーンとの統合が容易です。選択したコンパイラーによりすでにビルドされているアプリケーションは、ＳＹＣＬ コードが追加された後も引き続きビルドできます。プロジェクト内のソースファイルで SYCL ツールを使用すると、デバイス用にコンパイルされ、プロジェクトの残りは同じホスト・コンパイラーによって同一ソースファイルがコンパイルされます。リンクとライブラリーの関係には影響ありません。この設計により、既存のアプリケーションの SYCL への移植が簡素化されます。次に、この設計により、多くのベンダーが最適化されたツールチェーンを提供するデバイスごとに最適なコンパイラーを選択できます。
つまり、SYCL を使用することで、計算カーネルを通常の C++ コードとして C++ ソースファイル内に記述することができ、「単一ソース(Single Source)」プログラミングの概念を可能にします。ソフトウェア開発者は、マルチプラットフォーム、マルチデバイスの異種実行をサポートしながら、標準 C++ テンプレート手法を使用して一般的なアルゴリズムとデータ構造を開発および利用することができます。
基盤となる実装 (OpenCL など) の低レベル API へのアクセスもサポートされます。この仕様は、可能な限り多種多様なプラットフォー
ムでの実装を可能にするとともに、ほかのプラットフォーム固有のテクノロジーとの統合を容易にするように設計されているため、ユーザーと実装者の両方がシステム全体の異種処理のイノベーションをオープン・プラットフォームとして SYCL 上に構築できます。

第 2 章 はじめに | 16

SYCL 2020 リビジョン 6 - 3.1 概要

第 3 章 SYCL アーキテクチャー
この章では、ＳＹＣＬ アプリケーションの構造と、ＳＹＣＬ ジェネリック・プログラミング・モデルが多数の SYCL バックエンド上にどのように配置されるか説明します。

3.1. 概要SYCL は異種システムをプログラミングするオープンな業界標準です。SYCL の設計により、標準の C++ ソースコードを異種デバイス
またはホストのいずれかで実行できるように記述できます。
SYCL で使用される用語は、歴史的に OpenCL から継承されており、SYCL 固有のものがいくつか追加されています。ただし、SYCL はジェネリック C++ プログラミング・モデルであり、OpenCL 以外のほかの異種 API 上にも配置できます。SYCL 実装は、各種異種 APIに SYCL バックエンドを提供し、それらの上に SYCL 一般仕様を実装できます。この異種 API を SYCL バックエンド API と呼びます。
SYCL 一般仕様では、SYCL アプリケーションが期待通りに動作するよう、すべての SYCL 実装が SYCL ユーザーに公開する必要があ
る動作を定義しています。
SYCL バックエンド API により公開されたデバイスで実行できる関数オブジェクトは、SYCL カーネル関数と呼ばれます。
異なる SYCL バックエンド API との相互運用性を最大限にするため、ソフトウェア開発者は SYCL バックエンド相互運用ヘッダーをインクルードする場合、いつでも SYCL 汎用 API と SYCL バックエンド API にアクセスすることができます。ただし、相互運用性は SYCL
バックエンド固有の機能です。相互運用機能を使用するアプリケーションは、バックエンド間で移植できないため、SYCL の一般的なア
プリケーション・モデルに準拠していません。
SYCL のターゲットユーザーは、OpenCL のような標準化のすべてのパフォーマンスと移植性を必要とする C++ プログラマーですが、
ホスト/デバイスコードの境界を越えてより高いレベルの C++ 抽象化を利用する柔軟性を備えています。開発者は、テンプレート、クラス、オペレーターのオーバーロードなど、C++ の大部分の抽象化機能を使用できます。
ただし、一部の C++ 言語機能は、基盤となる異種プラットフォームの機能によって制限が課せられるため、カーネル内では許可されません。これらの機能には、仮想関数、仮想継承、例外のスロー/キャッチ、ランタイム型情報が含まれます。また、これらはカーネル外部で通常通り利用できます。これらの制限の範囲内で、開発者は SYCL で定義された抽象化を利用することも、独自の抽象化を SYCL 上に開発することもできます。これらの機能を備えた SYCL は、異種システムで動作する低レベルの高度にチューニングされたアルゴリズ
ムやデータ構造を高レベルのソフトウェア開発から分離したい開発者、ミドルウェア・プロバイダー、およびアプリケーション開発者にとっては理想的と言えます。ソフトウェア開発者は、ほかの分野の開発者が容易に利用できるテンプレート化されたアルゴリズムを作成できます。

3.2. SYCL アプリケーションの構造
以下は、利用可能な異種デバイスで並行して実行されるジョブをスケジュールする典型的な SYCL アプリケーションの例です。
1.

#include <iostream>2.

#include <sycl/sycl.hpp>

3.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::" は必要ありません

4.
5.
6.

int main() {int data[1024]; // 処理するデータを割り当てます7.
8.

// デフォルトキューを作成して、ワークをデフォルトデバイスへ送信します

9.

queue myQueue;

第 3 章 SYCL アーキテクチャー | 17

SYCL 2020 リビジョン 6 - 3.2 SYCL アプリケーションの構造
10.
11.

// SYCL ワークを {} ブロックで囲むことで、

12.

// resultBuf のデストラクターが待機するため、ブロックを終了する前に

13.

// すべての SYCL タスクを完了する必要があります

14.

{

15.

// データ変数をバッファーで囲みます16.

buffer<int, 1> resultBuf { data, range<1> { 1024 } };

17.
18.

// コマンドグループを作成して、キューにコマンドを発行します19.

myQueue.submit([&](handler& cgh) {20.

// 初期化なしでバッファーへの書き込みアクセスを要求

21.

accessor writeResult { resultBuf, cgh, write_only, no_init };

22.
23.

// 1024 個のワーク項目を持つ parallel_for タスクをキューに送信

24.

cgh.parallel_for(1024, [=](id<1> idx) {25.

// 0 から始まるランク番号でそれぞれのバッファー要素を初期化

26.

writeResult[idx] = idx;

27.

}); // カーネル関数の終端

28.

}); // コマンドキューの終端

29.

} // スコープの終端。キューに送信されたワークの完了を待機

30.
31.

// 結果をプリント

32.

for (int i = 0; i < 1024; i++)33.

std::cout << "data[" << i << "] = " << data[i] << std::endl;

34.
35.
36.

return 0;}

1 行目で、すべての SYCL 機能を提供する SYCL ヘッダーを #include します。
SYCL アプリケーションは SYCL プラットフォームで実行します。アプリケーションは、異なるセクションを指定する 3 つのスコープ、ア
プリケーション・スコープ、コマンド・グループ・スコープおよびカーネルスコープで構成されています。カーネルスコープは、デバイス・
コンパイラーによってコンパイルされ、デバイス上で実行される単一のカーネル関数を指定します。この例では、カーネルスコープは、
24 から 27 行目で定義されています。コマンド・グループ・スコープは、SYCL カーネル関数とアクセサーで構成されるワーク単位を指定します。この例では、コマンド・グループ・スコープは、19 から 28 行目で定義されています。アプリケーション・スコープには、コマンド・グループ・スコープ外のすべてのコードが含まれます。この 3 つのスコープは、3.9.12 節で説明されているように、SYCL 内で使用される各種オブジェクトのアプリケーション・フローと構造および存続期間を制御するために使用されます。
SYCL カーネル関数は、デバイス・コンパイラーでコンパイルされるスコープのコードブロックです。このコードはラムダ関数のボディー、または関数オブジェクトの operator() 関数で定義されます。SYCL カーネル関数の各インターフェイスは、必ずしも完全に独立しているわけではありませんが、単一の実行フローとして実行され、デバイス・コンパイラーが基盤となるデバイス向けに安全にコンパイルできるように許可される操作の制限に従う必要があります。
parallel_for メンバー関数は、クラスを使用してテンプレート化できます。このクラスは、ラムダを介して定義されたカーネルをデバッグする際にコンパイラーが生成する名前を回避する、カーネルにビルドオプションを適用するため既知の名前を提供する、または複数のコンパイラー・パスの実装と互換性を維持するなど、必要に応じてカーネルに手動で名前を付けるために使用されます。
parallel_for メンバー関数は、コマンドグループ内でキューに送信されるエンティティーであるカーネル・インスタンスを作成します。
parallel_for の場合、SYCL カーネル関数は、0 から 1023 までの指定する範囲で実行されます。カーネルを実行する各種メンバー関数は、4.9.4.2 節で説明します。

18 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.3 引用する規格
コマンド・グループ・スコープは、19 行目で示すようにコマンドグループ関数オブジェクトの構築でラップされた構文のスコープです。
コマンドグループ関数オブジェクトは、単一の SYCL カーネル関数のみを呼び出すことができ、ランタイムによって構築されるコマンド
グループの handler タイプのパラメーターを受け取ります。
3.7.1 節で説明されているように、カーネルが実行するすべての要件はコマンド・グループ・スコープで定義されています。9 行目のmyQueue に使用されるコンストラクターは、デフォルトのコンストラクターです。これにより、キューは実行時に最適なデバイスを選択でき、決定はランタイム時に行われます。
SYCL では、3.8 節で説明されるように、SYCL カーネル関数内で必要なデータは、バッファー、イメージまたは USM 割り当てに含まれていなければなりません。16 行目でバッファーを作成しています。バッファーへのアクセスは、21 行目で作成されるアクセサーを介して制御されます。バッファーはデータアクセスを追跡するために使用され、アクセサーはキュー上のデータへのアクセスを要求、および
SYCL カーネル関数の依存関係を追跡するために使用されます。この例では、26 行目でアクセサーを使用してバッファーにデータを書き込んでいます。

3.3. 引用する規格
以下に示すドキュメントは、この SYCL 仕様で参照されており、その内容は本仕様の要件でもあります。
1.

C++17: ISO/IEC 14882:2017 条項 1-19。この仕様では C++ コア言語と呼びます。SYCL 仕様は、次の C++ 言語の不具合レポートを実装するコンパイラーを想定しています (DR2325)。

2.

C++20: ISO/IEC 14882:2020 プログラミング言語—C++。この仕様では次世代 C++ 仕様と呼びます。

3.4. 非規格の注記と例
特に明記されない限り、この SYCL 仕様内の文書は規範的であり、SYCL 実装で必要な動作を定義します。非規範的/情報注記は、次の形式の「注記」アイコンを使用して示されます。

この形式の注記は、情報提供を目的としたものであり、ＳＹＣＬ 実装の要件や動作を指定するものではありません。

仕様で示すソースコードの例は、理解を補助するために提供されており、非規範的です。
非規範的な注記またはソースの例と仕様で説明する規範的な文書に矛盾がある場合、規範的な文書を正しく解釈する必要があります。

3.5. SYCL プラットフォーム・モデル
SYCL プラットフォーム・モデルは、OpenCL プラットフォーム・モデルをベースにしています。モデルは、デバイスと呼ばれる 1 つ以上の異種デバイスに接続されたホストで構成されます。
SYCL コンテキストは、ユーザーが直接、またはキューの作成時に暗黙的に構築され、SYCL ランタイムと SYCL バックエンドがデバイ
スまたはデバイスグループで動作するために必要なすべてのランタイム情報が含まれます。デバイスのグループを同じコンテキストでグループ化できる場合、デバイスは相互のメモリー・オブジェクトをある程度参照できます。SYCL ランタイムは、同じコンテキスト内のすべてのデバイスでメモリーが参照できると想定できます。同じプラットフォームに接続されるすべてのデバイスを同じコンテキストでグループ化できるとは限りません。
SYCL アプリケーションは、標準の C++ プログラムとしてホスト上で実行を開始します。デバイスは、異なる SYCL バックエンドを介して SYCL アプリケーションからアクセスされます。SYCL アプリケーションは、キューへコマンドグループ関数オブジェクトを送信します。各キューは、特定のデバイスでの実行を可能にします。

第 3 章 SYCL アーキテクチャー | 19

SYCL 2020 リビジョン 6 - 3.6 SYCL バックエンド・モデル
SYCL ランタイムは、コマンドグループ関数オブジェクトから、明示的なコピー操作や SYCL カーネル関数などの操作を抽出します。操作が SYCL カーネル関数である場合、SYCL ランタイムは SYCL バックエンド固有のメカニズムを使用して、SYCL アプリケーションからデバイスバイナリーを抽出しデバイスで実行するため異種 API に渡します。
SYCL デバイスは 1 つ以上の計算ユニット (CU) に分割され、それぞれが 1 つ以上の処理要素 (PE) に分割されます。デバイス上での計算は処理要素で行われます。計算が PE にどのようにマッピングされるかは、SYCL バックエンドおよびデバイス固有です。2 つの異なるバックエンドに対応する 2 つのデバイスは、同じデバイスであっても異なる方法で計算をマッピングできます。
SYCL アプリケーションに SYCL カーネル関数オブジェクトが含まれる場合、SYCL 実装はデバイスバイナリーを SYCL アプリケーションに統合することを可能にするオフラインコンパイルのメカニズムを提供する必要があります。オフライン・コンパイラーの出力は、実行中にファイナライズされる SPIR-V などの中間表現、または最終デバイスの ISA にすることができます。
デバイスは、ビルトイン関数として特殊用途の機能を用意する必要があります。SYCL API は、前述のビルトイン関数を照会およびディ
スパッチする関数を提供します。一部の SYCL バックエンドとデバイスは、プログラム可能なカーネルをサポートせずビルトイン関数のみをサポートする場合があります。

3.6. SYCL バックエンド・モデル
SYCL は、OpenCL など複数の異種 API をターゲットにできる C++ 言語のジェネリック・プログラミング・モデルです。
SYCL 実装は、SYCL バックエンドを実装することで、これらのターゲット API を有効にします。SYCL 実装が前述の SYCL バックエンドに準拠するには、バックエンドで SYCL ジェネリック・プログラミング・モデルを実行する必要があります。すべての SYCL 実装は少なくとも 1 つのバックエンドを実装する必要があります。
このドキュメントでは、すべての SYCL バックエンドで利用可能な SYCL ジェネリック・インターフェイスについて説明します。SYCL ジェ
ネリック・インターフェイスが特定の SYCL バックエンドにどのようにマッピングされるかは、Khronos SYCL Group によって提供される個別の SYCL バックエンド仕様ドキュメント、または SYCL 実装ドキュメントで定義されます。SYCL バックエンド仕様が存在する場
合は、常に、SYCL 実装ドキュメントよりも優先されます。
SYCL ユーザーが SYCL アプリケーションを作成する場合、SYCL アプリケーションの構築に使用する SYCL バックエンドを決定します。これは、「アクティブ・バックエンド」のセットと呼ばれます。実装では、ユーザーが選択したアクティブ・バックエンドを実行時に
SYCL 実装で同時に利用できるようにする必要があります。コンパイル時に 2 つのバックエンドが利用可能で、実行時に無効な SYCL
アプリケーションを生成する場合、SYCL 実装はコンパイルエラーを出力する必要があります。
複数のアクティブ・バックエンドで生成された SYCL アプリケーションは、必ずしもそのバックエンドが実行できることを保証するもの
ではありません。実行時に利用可能なアクティブ・バックエンドのサブセットは、利用可能なバックエンドと呼ばれます。バックエンドは、
SYCL アプリケーションが実行されるホスト・プラットフォームが SYCL バックエンドに必要な異種 API をサポートしている場合に利用可能であると言われます。
特定のバックエンドでサードパーティーのライブラリーをシステムで利用できるようにするかどうかは、実装によって異なります。実行時にすべてのアクティブ・バックエンドで必要な依存関係が解決されないと、SYCL アプリケーションは実行されません。
アプリケーションが実行されると、ユーザーは利用可能な SYCL プラットフォームを照会できます。SYCL 実装では、プラットフォームにグループ化された各バックエンドによって提供されるデバイスが示されます。バックエンドは少なくとも 1 つのプラットフォームをサポートする必要があります。
SYCL バックエンド・モデルでは、SYCL オブジェクトに特定の SYCL バックエンド・ネイティブ・タイプへの複数の参照を含めることができます。すべての SYCL オブジェクトが SYCL バックエンド・ネイティブ・タイプに直接マップされるわけではありません。SYCL オブジェ
クトの SYCL バックエンド・ネイティブ・タイプへのマッピングは、SYCL バックエンド仕様ドキュメント、または SYCL 実装によって定義されます。

20 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.7 SYCL 実行モデル
複数の SYCL バックエンド・オブジェクトが相互に利用できることを保証するため、SYCL メモリー・オブジェクトは特定の SYCL バック
エンドに関連付けられません。SYCL メモリー・オブジェクトには、利用可能なバックエンドに関連する任意のデバイスからアクセスできます。SYCL 実装は、SYCL メモリー・オブジェクトを異なる SYCL バックエンドの複数のネイティブタイプにマップできる可能性があります。
SYCL メモリー・オブジェクトは、特定の SYCL バックエンドから独立しているため、SYCL コマンドグループは、SYCL バックエンドによって割り当てられたメモリー・オブジェクトへのアクセスを要求して、キューに関連付けられたバックエンドで実行できます。それには、
SYCL 実装が SYCL バックエンド間でメモリー・オブジェクトを転送できるようにする必要があります。
USM 割り当てには、4.8 節で説明される制限が適用されます。
SYCL アプリケーションが SYCL バックエンド固有の動作や相互関係に依存せず、任意の SYCL バックエンドで実行される場合、それは SYCL ジェネリック・アプリケーションと呼ばれ、アプリケーションが必要とする機能をサポートする SYCL 準拠の実装で実行されることが期待されます。

3.6.1. プラットフォーム混在バージョンのサポート
SYCL ジェネリック・プログラミング・モデルは、多数のプラットフォームで利用でき、各プラットフォームは多くのデバイスをサポートします。各プラットフォームは、特定の SYCL バックエンドに関連付けられます。プラットフォームに関連付けられる SYCL デバイスは、同時にその SYCL バックエンドに関連付けられます。
SYCL ジェネリック・プログラミング・モデルの API は、仕様に従って定義され、仕様バージョンは SYCL_LANGUAGE_VERSION マク
ロで示されますが、これは SYCL バックエンドが提供する API には適用されません。SYCL バックエンドは、API を定義するそれぞれのドキュメントを提供し、それにはデバイスとプラットフォームのバージョンを照会する方法が含まれます。

3.7. SYCL 実行モデル
3.2 節に示すように、SYCL アプリケーションは、アプリケーション・スコープ、コマンド・グループ・スコープ、およびカーネルスコープの3 つで構成されます。アプリケーション・スコープとコマンド・グループ・スコープのコードはホスト上で実行され、「SYCL アプリケーショ
ン実行モデル」によって管理されます。カーネルスコープ内のコードはデバイス上で実行され、「SYCL カーネル実行モデル」によって管理されます。
SYCL デバイスは、必ずしも物理的なアクセラレーターに準ずる必要はありません。SYCL 実装では、ホストのリソー
スの一部分またはすべてを SYCL デバイスとして利用することを選択できます。そのような実装では、コードはホスト上のカーネルスコープで実行されますが、そのコードは「SYCL カーネル実行モデル」によって管理されます。

3.7.1. SYCL アプリケーション実行モデル
SYCL アプリケーションは、それぞれのカーネルとその要件をコマンドグループ関数オブジェクトとしてグループ化することで、カーネルの実行順序を定義します。コマンドグループ関数オブジェクトは、カーネルを実行するデバイスを定義するキュー・オブジェクトを介してデバイスに送信されます。この仕様では、これを「カーネルをデバイスに送信する」と呼ぶことがあります。
同じコマンドグループを異なるキューに送信することもできます。コマンドグループが SYCL キューに送信されると、カーネルを実行する要件が取得されます。実装は、要件が満たされると直ちにカーネルの実行を開始できます。

第 3 章 SYCL アーキテクチャー | 21

SYCL 2020 リビジョン 6 - 3.7 SYCL 実行モデル

3.7.1.1. SYCL アプリケーションによって管理される SYCL バックエンドのリソース
SYCL アプリケーションと統合された SYCL ランタイムは、アクセス可能な異種デバイスを管理するため、SYCL バックエンド API が必要とするリソースを管理します。これには、リソースハンドラー、メモリープール、ディスパッチ・キュー、およびそのほかのテンポラリー・
ハンドラー・オブジェクトが含まれますが、必ずしもこれらに限定されません。
SYCL プログラミング・インターフェイスは、RAII ルールを適用して SYCL アプリケーションによって管理されるリソースの存続期間を示します。SYCL オブジェクトの構築では、通常、複数の SYCL バックエンド・オブジェクトを作成する必要があります。これらのオブジェ
クトは、SYCL オブジェクトが破棄されると適切に解放されます。構築と破棄の全体的な規則については、4 章で説明します。SYCL バッ
クエンドのドキュメントでは、SYCL オブジェクトが SYCL バックエンドにどのようにマッピングされるか、リソース管理について詳しく説明しています。
SYCL において、デバイスにワークを送信するために最小限必要なオブジェクトはキューです。キューには、プラットフォーム、デバイス
およびコンテキストへの参照が含まれます。
SYCL によって管理されるリソースを以下に示します。
1.

プラットフォーム: SYCL バックエンド API のすべての機能はプラットフォームによって実装されます。プラットフォームは、特定のベンダーのランタイムやそれを介してアクセス可能なデバイスと見なすことができます。一部のデバイスはベンダー
固有のラン タ イム にの みア ク セスでき る こ とから、 複数の プラットフォ ーム が存在す る場合もあり ます。 SYCL は
sycl::platform オブジェクトを介してアクセスできるユーザーの多様なプラットフォームを管理します。

2.

コンテキスト: ユーザーが取得したすべての SYCL バックエンドのリソースはコンテキストにアタッチされます。コンテキス
トにはホストが利用できるデバイスのコレクションが含まれ、デバイス間で共有されるメモリー・オブジェクトを管理します。
同じコンテキストに属するデバイスは、実装固有のメカニズムを使用して互いのグローバルメモリーにアクセスできる必要があります。特定のコンテキストは単一のプラットフォームが所有するデバイスのみを包括できます。ユーザーは
sycl::context オブジェクトを介してコンテキストを利用できます。

3.

デバイス: プラットフォームは、SYCL カーネルを実行する 1 つ以上のデバイスを提供します。SYCL では、デバイスは
sycl::device オブジェクトを介してアクセスできます。

4.

カーネル: SYCL デバイスで実行される SYCL 関数は、C++ 関数オブジェクト (名前付き関数オブジェクトまたはラムダ関数) として定義されます。カーネルは sycl::kernel オブジェクトを介して内部を調査できます。

一部の SYCL バックエンドは、非プログラマブルな機能を事前定義カーネルとして提供する場合があることに注意してください。
5.

カ ー ネ ル バ ン ド ル : カ ー ネ ル は 、 SYCL ア プ リ ケ ー シ ョ ン 内 部 に デ バ イ ス イ メ ー ジ と し て 保 持 さ れ 、 デ バ イ ス は
sycl::kernel_bundle オブジェクトにグループ化されます。これらのオブジェクトは、アプリケーションがデバイスのカーネ
ルをオンラインコンパイルする方法を提供します。

6.

キュー: SYCL カーネルはコマンドキューを実行します。ユーザーは、関連するコンテキスト、プラットフォーム、およびデバイスを参照する sycl::queue オブジェクトを作成する必要があります。コンテキスト、プラットフォーム、およびデバイスは、自動的に選択されるか、ユーザーが指定できます。SYCL キューは、特定のコンテキストの特定のデバイスでカーネルを実行しますが、利用可能な SYCL バックエンドの任意のデバイスと関係を持つことができます。

SYCL 実装は、ユーザーが SYCL 相互運用 API を介して手動で取得したものを除き、SYCL バックエンド API で処理されるリソースを正しく初期化し破棄することを保証します。

3.7.1.2. SYCL コマンドグループと実行順序
デフォルトでは、SYCL キューは、依存関係情報に基づいて順不同でカーネル関数を実行します。開発者は、特定のカーネルを実行するのに必要なデータを用意するだけで済みます。

22 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.7 SYCL 実行モデル
SYCL ランタイムは、カーネルが正当性を保証する順番で実行されることを保証します。アクセスモードとメモリータイプを指定することで、実行時にカーネルの有向非巡回依存グラフ (DAG) が作成されます。これは、コマンド・グループ・オブジェクトによって行われます。
コマンド・グループ・オブジェクトは、一連の必要条件 (R) とカーネル関数 (k) を定義します。sycl::queue::submit メンバー関数を使用
して、コマンドグループをキューに送信します。
必要条件 (ri) はカーネル関数 (k) を特定のデバイスで実行するために満たす必要がある要件です。例えば、特定のデータがデバイスで利用可能である、またはほかのコマンドグループが実行を完了している、という要件があります。実装は、コマンドグループの送信後にいつでも要件を評価できます。「コマンドグループの処理」は、SYCL ランタイムが与えられた R のすべての要件を評価するプロセスです。SYCL ランタイムは、すべての ri が満たされるときにのみ (すべての要件が満たされた場合) k を実行します。表記を簡単にするため、仕様では foo という名前のコマンドグループの要件セットを CGfoo = r1, …, rn.と表します。
要件の評価 (Satisfied(ri)) は、True または False で要件の状態を返します。「Satisfied」要件とは、要件が満たされていることを意味します。Satisfied(ri) は要件を変更するものではなく、現在の状態を監視するだけです。実装は要件のチェックをブロックしないため、同じチェックを複数回実行できます。
アクション (ai) は、要件を満たすために実行する必要がある実装定義の操作のコレクションです。要件を満たす操作が必要ない場合、与えられたコマンドグループ A の一連のアクションを空状態にできます。ai は ri. を満たすために必要なアクションです。異なる要件のアクションは、相互作用なしで任意の順番で適用できます (2 つの要件 rj と rk、(rj, rk) ≡ (rk, rj) が与えられた場合など)。2 つのアクションの共通部分は空である必要はありません。アクションには、メモリーコピー操作、マッピング操作、ホスト側の同期、または実行固有の動作が含まれますが、これらのみに限定されるわけではありません。
最後に、アクションの実行 (Perform(ai)) は、要件 rj. を満たすために必要なアクション操作を実行します。Perform(ai) の実行後、評価
Satisfied(rj) はカーネルが実行されるまで True を返すことに注意してください。カーネルが実行されると、同じ要件を持つ別のコマンドグループがアクションを再び実行する必要があるかどうかは未定義ですが、同じコマンド・グループ・オブジェクト内の異なる要件のアクションは、相互作用なしに任意の順番で適用できます。2 つの要件 rj と rk が与えられる場合、Perform(aj) の後に Perform(ak) が続
くのと、Perform(ak) に Perform(aj) が続くのは同等です。
同一キューまたは異なるキューに送信された異なるコマンドグループの要件は、送信された順番に評価されます。要件セットの共通部
分が空ではないコマンド・グループ・オブジェクトは、互いに依存関係があると言われ、キューに送信された順番で実行されます。コマンドグループが異なるキューまたは複数のスレッドによって送信される場合、実行の順序は SYCL ランタイムによって決定されます。独
立したコマンド・グループ・オブジェクトは、依存関係にかかわりなく同時に送信することができます。
表 1 は、3 つのコマンド・グループ・オブジェクト (CGa,CGb,CGc) の実行順序を示しており、特定の要件が同じキューに送信されていることが分かります。CGa と CGb の両方には、それぞれ r1 と r2 要件のみがあります。CGc は r1 と r2 の両方を必要とします。SYCL ランタイ
ムは、CGa と CGb を同時に実行できますが、CGc は CGa と CGb の両方が完了するまで待機する必要があります。SYCL ランタイムは、要件を評価して、(存在する場合) CGa と CGb に必要なアクションを実行します。CGa と CGb が完了した後に、CGc 要件の評価は満たされます。
表 1. 同一キューに送信された 3 つのコマンドグループの実行順序コマンドグループ
SYCL アプリケーションのエンキュー順序SYCL カーネルの実行順序

sycl::queue syclQueue;
syclQueue.submit(CGa(r1));
syclQueue.submit(CGb(r2));
syclQueue.submit(CGc(r1,r2));
表 2 では、3 つの SYCL キュー・オブジェクトを使用して、表 1 と同じコマンド・グループ・オブジェクトを送信しています。3 つの異なるキューを使用するかどうかにかかわりなく、異なるコマンド・グループ・オブジェクトの実行順序は同じです。異なるスレッドが異なる
キューに送信する場合、コマンドグループの実行順序は送信メンバー関数が実行される順序になります。この場合、異なるコマンド・グ

第 3 章 SYCL アーキテクチャー | 23

SYCL 2020 リビジョン 6 - 3.7 SYCL 実行モデル
ループ・オブジェクトは異なるデバイスで実行されるため、要件を満たすアクションは異なる場合があります (SYCL ランタイムは別のコ
ンテキストで別のデバイスにデータをコピーすることが必要となる場合があります)。
表 2. 異なるキューに送信された 3 つのコマンドグループの実行順序
SYCL アプリケーションのエンキュー順序SYCL カーネルの実行順序

sycl::queue syclQueue1;
sycl::queue syclQueue2;
sycl::queue syclQueue3;
syclQueue1.submit(CGa(r1));
syclQueue2.submit(CGb(r2));
syclQueue3.submit(CGc(r1,r2));

3.7.1.3. イベントによる実行順序の制御
実行するアクションを送信すると、event オブジェクトが返されます。プログラマーは、このイベントを使用してプログラムを明示的に同期できます。ホストコードは、イベントの完了を待機できます。これにより、イベントに対応するアクションが完了するまで、ホストの実行がブロックされます。event クラスの詳細は、4.6.6 節をご覧ください。
イベントを使用してカーネルの実行を明示的に順序付けできます。ホストコードは、特定のイベントの完了を待機することがあります。
これにより、イベントに対応するアクションが完了するまで、ホストの実行がブロックされます。イベントは、コマンドグループ間の要件を定義することもあります。この方法でイベントを使用すると、別のコマンドグループが実行を開始する前に、1 つ以上のコマンドグ
ループの完了が必要であることがランタイムに通知されます。詳細については、4.9.4.1 節をご覧ください。

3.7.2. SYCL カーネル実行モデル
カーネルが実行のため送信されると、インデックス空間が定義されます。カーネルボディーのインスタンスは、インデックス空間の各ポイントで実行されます。カーネル・インスタンスは work-item (ワーク項目) と呼ばれ、グローバル id を提供するインデックス空間内のポイントで識別されます。それぞれの work-item は同じコードを実行しますが、コードと操作されるデータの実行パスは、work-itemのグローバル id を使用して計算を特殊化することで異なります。
サイズゼロのインデックス空間は許可されます。カーネル関数自体が実行されないことを除いて、カーネル実行のすべては通常どおりに動作します。コマンドキューは要件を満たした後そのカーネルをスケジュールし、これにより関連するエンキューされたカーネルの要件が満たされます。

3.7.2.1. 基本カーネル
SYCL は、range<N> (N は1、2 または 3) で定義される N 次元のインデックス空間でカーネルを呼び出す単純な実行モデルをサポートします。この場合、カーネルの work-item は独立して実行されます。
各 work-item は、タイプ item<N> の値によって識別されます。タイプ item<N> は、タイプ id<N> の work-item 識別子と、カーネルを実行する work-item の数を示す range<N> をカプセル化します。

3.7.2.2. ND-range カーネル
work-item は インデックス空間よりも粗い粒度の分解を提供するワークグループに構成できます。それぞれの work-group には、
work-item で使用できるインデックス空間と同じ次元の work-group id が割り当てられます。ｗork-item には、それぞれ work-group24 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.8 メモリーモデル内で一意のローカル id が割り当てられるため、単一 work-item は、グローバル id、またはローカル id と work-group id の組み合わせで識別できます。特定の work-group 内の work-item は、単一の計算ユニットの処理ユニットで同時に実行されます。
SYCL で使用される work-group は、ND-range と呼ばれます。ND-range は、N 次元のインデックス空間であり、N は 1、2、または 3 です。SYCL では、ND-range は nd_range<N> クラスを介して表現されます。nd_range<N> は、グローバルレンジとローカルレンジで構成され、それぞれ range<N> タイプの値で表現されます。さらに、タイプ id<N> 値で表現されるグローバルオフセットが存在することもありますが、これは SYCL 2020 では非推奨です。タイプ range<N> と id<N> は、それぞれ N 要素の整数配列です。nd_range<N>で定義される反復回数は、ND-range のグローバルオフセットで開始される N 次元のインデックス空間であり、サイズはグローバルレ
ンジで、ローカル・レンジ・サイズの work-group に分割されます。
Nd-range の各 work-item は、タイプ nd_item<N> の値によって識別されます。タイプ nd_item<N> は、グローバル id、ローカル id、および work-group id をすべて id<N> (id<N> タイプの反復空間オフセットですが、SYCL 2020 では非推奨) としてカプセル化し、グローバルとローカルレンジを同期して work-group を有効にします。ｗork-group には、work-item のグローバル id と同様の方法でid が割り当てられます。ｗork-item には work-group とゼロからその次元の work-group サイズから 1 を引いた範囲のコンポーネン
トを保持するローカル id が割り当てられます。つまり、work-group id と work-group 内のローカル id の組み合わせで work-item が一意に定義されます。

3.7.2.3. バックエンド固有のカーネル
SYCL は、SYCL バックエンドで固定機能を非プログラマブルなビルトイン関数として提供できます。これらのビルトインカーネルの可用性と動作は SYCL バックエンド固有であり、SYCL 実行モデルとメモリーモデルに従う必要はありません。さらに、このビルトイン
カーネルを使用するインターフェイスも SYCL バックエンド固有です。詳しくは、関連するバックエンドの仕様を参照してください。

3.8. メモリーモデル
SYCL は単一ソース・プログラミング・モデルであるため、メモリーモデルはアプリケーションとデバイスカーネルの両方に影響します。
SYCL アプリケーションでは、SYCL ランタイムがカーネルの実行にデータが利用可能であるかを確認します。SYCL デバイスカーネル
では、特定のデバイスでのメモリー動作を記述する SYCL バックエンド・ルールによって SYCL C++ 構造にマップされます。つまり、純粋に C++ の機能を使用して効率良くカーネルを記述することができます。

3.8.1. SYCL アプリケーションのメモリーモデル
ホストで実行されるアプリケーションは、sycl::buffer クラスや USM 割り当て関数のインスタンスを使用して、SYCL バッファー・オブ
ジェクトを介してグローバルアドレス空間にメモリーを割り当てるか、sycl::unsampled_image および sycl::sampled_image クラス
により特殊なイメージメモリーを割り当てることができます。
SYCL アプリケーションでは、メモリー・オブジェクトは SYCL コンテキストに関係なく、使用されるすべてのデバイスにバインドされます。SYCL メモリー・オブジェクト (バッファーとイメージ・オブジェクト) は、複数のベースとなる SYCL バックエンドのメモリー・オブジェ
クトをホストメモリーに割り当ててカプセル化し、同じオブジェクトを異なるコンテキスト、プラットフォーム、またはバックエンドのデバイス間で共有できるようにします。USM 割り当ては、メモリー割り当てを一意に識別して SYCL コンテキストにバインドします。これは、コンテキストで使用されるバックエンドでのみ有効です。
コマンド・グループ・オブジェクトの実行順序により、異なるデバイスからメモリー・オブジェクトへ一貫した順序でのアクセスが保証されます。USM 割り当てにアクセスしても、実行の順番は変わりません。ユーザーは、正規の実行に必要な要件を SYCL ランタイムに明示的に通知しなければなりません。
メモリー・オブジェクトにアクセスするには、ユーザーはカーネルまたはホストが必要とするメモリー・オブジェクトへのアクセスタイプ
をパラメーター化するアクセサー・オブジェクトを作成する必要があります。アクセサー・オブジェクトではメモリー・オブジェクトにアク

第 3 章 SYCL アーキテクチャー | 25

SYCL 2020 リビジョン 6 - 3.8 メモリーモデル
セスする要件を定義します。この要件は、カーネルまたはホストで使用されるかにかかわりなくアクセサー構造で定義されます。アクセ
サー・オブジェクトは、アクセスがグローバルメモリー、定数メモリー、またはイメージメモリーのいずれを経由するか、そしてそれらに関連するアクセス関数を指定します。アクセサーは、アクセスが読み取り専用 (RO)、書き込み専用 (WO) または読み取り/書き込み(RW) のいずれであるかも指定します。オプションの no_init プロパティーをアクセサーに追加して、アクセサーが参照するデータより古いコンテンツを破棄するようにシステムに指示できます。これには no-init-write-only (NWO) と no-init-read-write (NRW) の 2 つの追加要件タイプがあります。必要要件が特定のアクセスモードのアクセサー・オブジェクトを表す場合、MemoryObjectAccessMode として示します。例えば、RW モードでメモリーアクセス buf1 にアクセスするアクセサーは buf1RW と示されます。このようなアクセサーを使用するコマンド・グループ・オブジェクトは、CG(buf1RW) のように表されます。必要条件を満たすアクションとメモリー・オブジェクトの最新のコピーがある場所は実装によって異なります。
表 3 は、コマンド・グループ・オブジェクトが、異なるコンテキストのデバイスで実行される 2 つの個別の SYCL キューにエンキュー (送信) される例を示しています。コマンドグループの実行に必要な要件は同じですがアクションは異なります。例えば、実行前にデータがホストにある場合、A(b1RW) と A(b2RW) は、それぞれ context1 または context2 へのコピー操作として実行できることが考えられます。

CGa と CGb が実行された後、カーネルの実行結果がデバイスにとどまる可能性があるため、A'(b1RW) は空の操作になることがあります。
一方、CGb の結果は、CGc が実行するコンテキストとは異なるコンテキストにあるため、A'(b2RW) は実装固有のメカニズムを使用して 2
つの個別のコンテキスト間でデータをコピーする必要があります。
表 3. 3 つのコマンドグループが異なる 2 つのキューに送信された場合のアクション
SYCL アプリケーションのエンキュー順序SYCL カーネルの実行順序

sycl::queue q1(context1);
sycl::queue q2(context2);
q1.submit(CGa(b1RW));
q2.submit(CGb(b2RW));
q1.submit(CGc(b1RW,b2RW));SYCL ランタイムによる可能な実装

表 3 は、3 つのコマンドグループが異なる 2 つのキューに送信された場合のアクションと、SYCL ランタイムによる OpenCL SYCL バッ
クエンドの潜在的な実装を示しています。この例では、それぞれの SYCL バッファー (b2,b2) がコンテキストごとに個別の cl_mem オ
ブジェクトとして実装されていることに注目してください。
コマンドグループ内でアクセサーを定義する順番は、それらが定義する要件とは無関係であることに注意してください。すべてのアクセ
サーは、常にそれらが定義されるコマンド・グループ・オブジェクト全体に適用されます。
同じコマンドグループ内の複数のアクセサーが同じメモリー・オブジェクトに対し異なる要件を定義する場合、それらの要件を解決する必要があります。
最初に、アクセスモードが異なってもアクセスターゲットが同じであるすべての要件は、表 4 に従ってアクセスモードを結合した単一の要件として解決されます。アトミック・アクセス・モードは、結合された要件を解決する際に読み取り/書き込み (RW) として機能します。
表 4 の規則は可換であり連想性を持ちます。

26 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.8 メモリーモデル
表 4. 同じコマンドグループ内の 2 つのアクセサーのアクセスモードの結合要件。規則は可換であり連想性を持ちます。
単一アクセスモード

ほかのアクセスモード

複合要件

read (RO)write (WO)

read-write (RW)

read (RO)read-write (RW)

read-write (RW)

write (WO)

read-write (RW)

read-write (RW)

初期化なし write (NWO)

初期化なし read-write (NRW)

初期化なし read-write (NRW)

初期化なし write (NWO)

write (WO)

write (WO)

初期化なし write (NWO)

read (RO)read-write (RW)

初期化なし write (NWO)

read-write (RW)

read-write (RW)

初期化なし read-write (NRW)

write (WO)

read-write (RW)

初期化なし read-write (NRW)

read (RO)read-write (RW)

初期化なし read-write (NRW)

read-write (RW)

read-write (RW)

これにより、同じアクセスターゲットを持つ必要条件は存在しなくなります。
次に、残りの要件は次の規則に従う必要があります。要件のうち 1 つだけが書き込みアクセス (W または RW) を持ちます。そうでない
場合、SYCL ランタイムは例外をスローする必要があります。すべての必要条件は対象データが指定されたアクセスターゲットで利用可能になるための要件を作成しますが、書き込みアクセス権限を持つ必要条件のみがコマンドグループに影響します。つまり、その必要条件が表すデータのみが更新されます。
例:• CG(b1GRW, b1HR) は許可されます。
• CG(b1GRW, b1HRW) は許可されません。
• CG(b1GW, b1CRW) は許可されません。
ここで、G と C は、target::device と target::constant_buffer アクセサーに対応し、H はホストアクセサーに対応します。
既存のバッファーレンジから作成されたバッファーはサブバッファーと呼ばれ、バッファーは任意の数のサブバッファーでオーバーレイ
できます。これらのサブバッファーを操作するアクセサーを作成できます。サブバッファーの作成と制限については、4.7.2 節をご覧ください。サブバッファーにアクセスする要件は、そのレンジを指定することで表現されます。例えば、 CG(b1RW,[0,5)) は、読み取り/書き込み
モードでレンジ [0,5) のバッファー b1 にアクセスする要件を示します。
2 つのアクセサーが同じバッファーにアクセスするように構成され、両方が重複しないサブバッファーにある場合、2 つのアクセサーは重複しないと考えられます。そうでなければ、アクセサーは重複します。重複 (オーバーラップ) は、コマンドグループのスケジュールの順番を決定するために行われるテストです。要件が重複しないコマンドグループは同時に実行できます。

第 3 章 SYCL アーキテクチャー | 27

SYCL 2020 リビジョン 6 - 3.8 メモリーモデル
表 5. 重複するサブバッファーと重複しないサブバッファーの要件
SYCL アプリケーションのエンキュー順序SYCL カーネルの実行順序

sycl::queue q1(context1);
q1.submit(CGa(b1{RW,[0,10)}));
q1.submit(CGb(b1{RW,[10,20)));q1.submit(CGc(b1RW,[5,15)));
データをコピーせず読み取るだけのコマンドグループは、読み取り後にデータをホストまたはほかのデバイスに戻さず、ランタイムは
複数のデバイス間でデータの複数の読み取り専用コピーを維持することができます。
特殊なケースの要件はホストアクセサーで定義されます。ホストアクセサーは、 H(MemoryObjectAccessMode) で示されます。例えば、

H(b1RW) は読み取り/書き込みモードの b1 へのホストアクセサーを表します。ホストアクセサーはコマンドグループ外のメモリー・オブ
ジェクトから構築される特殊なタイプのアクセサーであり、指定されたメモリー・オブジェクトに関連するデータは指定されたポイン
ターのホストで利用可能でなければなりません。これにより、要件が満たされるまでランタイムはこのオブジェクトの構築をブロックします。ホスト・アクセサー・オブジェクトは、特定のメモリー・オブジェクトへのすべてのアクセスに対するバリアです。表 6 は、同じキューに投入された複数のコマンドグループの例を示しています。ホストアクセサー H(b1RW) に到達すると、CGa が終了するまで実行を続行できません。ただし、 CGb は b1 に関連する要件がないため、バリアと同時に実行できます。最後に、CGc は H(b1RW) が終了した後にキューに投入されますが、CGb はすべての要件が満たされるまで完了を待機する必要があります。同期規則の詳細については、3.9.8 節をご覧ください。
表 6. ホストアクセサーを使用したコマンドグループの実行
SYCL アプリケーションのエンキュー順序SYCL カーネルの実行順序

sycl::queue q1;
q1.submit(CGa(b1RW));
q1.submit(CGb(b2RW));
H(b1RW);
q1.submit(CGc(b1RW, b2RW));

3.8.2. SYCL デバイスのメモリーモデル
SYCL デバイスのメモリーモデルは、OpenCL 1.2 の メモリーモデルを基にしています。カーネルで実行される work-item は、3 つの異なるアドレス空間 (メモリー領域) と、いくつかのアドレス空間と重複する仮想アドレス空間にアクセスできます。

• グローバルメモリーは、すべての work-group のすべての work-item にアクセスできます。work-item は、グローバル・メモリー・
オブジェクトの任意の要素を読み取りまたは書き込みできます。グローバルメモリーの読み取りと書き込みは、デバイスの機能に応じてキャッシュされることがあります。グローバルメモリーはカーネル呼び出しの間は永続的ですが、同時に実行される 2 つ以
上のカーネルが USM が割り当てられた場所に同時にアクセスし、少なくとも 1 つのカーネルがその場所を変更するとデータ競合が発生します。メモリーフェンスまたはアトミック操作を使用しない限り、正しい結果が得られる保証はありません。

• ローカルメモリーは、単一の work-group のすべての work-item にアクセスできます。あるワークグループのローカルメモリーに別のワークグループからアクセスすると動作は未定義です。このメモリー領域は、work-group 内のすべての work-item によって共有される変数を割り当てるために使用されます。work-group-level の可視性により、適切であればローカルメモリーをデバ
イスメモリーの専用領域として実装できます。

• プライベート・メモリーは work-item 専用のメモリー領域です。特定の work-item のプライベート・メモリーに別の work-item からアクセスすると動作は未定義です。

28 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.8 メモリーモデル• 汎用メモリーは、グローバル、ローカル、およびプライベート・アドレス空間と重複する仮想アドレス空間です。

3.8.2.1. メモリーアクセス
デバイスカーネルのアクセサーは、対応するアドレス空間へのポインターとして機能し、メモリー・オブジェクトへのアクセスを可能にします。
実装が USM をサポートする場合、カーネル引数としてポインターを直接渡すことができます。カーネル内のホストから渡されたポイン
ターの逆参照が許可される場合の詳細は、4.8 節を参照してください。
カーネル内にローカルメモリーを割り当てるには、sycl::local_accessor オブジェクトを引数として ND-range カーネル (ユーザー定義の work-group サイズを持つ) に渡すか、sycl::parallel_for_work_group 内の work-group スコープで変数を定義できます。
sycl::parallel_for スコープまたは sycl::parallel_for_work_item スコープ内で定義された変数は、プライベート・メモリーに割り当てられます。sycl::parallel_for_work_group スコープ内で定義された変数はすべてローカルメモリーに割り当てられます。
ユーザーは、バッファー全体だけでなくサブバッファーも参照するアクセサーを作成できます。
カーネル内部では、ベースとなる C++ ポインタータイプをアクセサーから取得できます。ポインタータイプには、コンパイル時に推測されるアドレス空間が含まれます。例えば、C++ ポインターがグローバルメモリーへのアクセサーから取得されると、C++ ポインタータイ
プにはグローバルアドレス空間属性がアタッチされます。アドレス空間属性は、定義されたアルゴリズムを使用してあるポインターが別のポインター値に初期化される場合、コンパイル時に別のポインター値に伝搬されます。
開発者がポインター値のアドレス空間を明示的に指定する必要がある場合は、明示的なポインタークラスの 1 つを利用できます。それぞれ の ア ド レ ス 空 間 に は 、 次 の よ う に 異 な る 明 示 的 ポ イ ン タ ー ク ラ ス が あ り ま す : sycl::raw_local_ptr 、 sycl::raw_global_ptr 、
sycl::raw_private_ptr 、 sycl::raw_generic_ptr 、 sycl::decorated_local_ptr 、 sycl::decorated_global_ptr 、 sycl::decorated_private_ptr
または sycl::decorated_generic_ptr。
decorated プリフィクス・ポインターを持つクラスは、実装定義されたアドレス空間修飾を使用するポインターを示しますが、raw プリ
フィクスを持つクラスは提供されません。アクセスターゲット target::device または target::constant_buffer を持つバッファーアクセ
サー、およびローカルアクセサーは明示的なポインタークラス (multi_ptr) に変換できます。
テンプレートがさまざまなアドレス空間に対応する必要がある場合、アドレス空間を指定するにはコンパイル時に定数列挙値を使用してテンプレート化される sycl::multi_ptr クラスが定義されます。

3.8.3. SYCL メモリー一貫性モデル
SYCL メモリー一貫性モデルは、C++ コア言語のメモリー一貫性モデルをベースにします。SYCL がメモリーの一貫性に影響する可能性があるクラスおよび関数の拡張機能を提供する場合、拡張機能が使用されないデフォルトの動作は常に標準の C++ の動作と一致します。
SYCL 実装では、ホストコードとデバイスコード間で同じメモリー一貫性モデルが使用されることを保証する必要があります。デバイス・
コンパイラーは、3.9.1 節で説明される C++ の最小バージョンで定義されるメモリーモデルをサポートする必要があります。C++ の追加バージョンをサポートする SYCL 実装は、対応するメモリーモデルもサポートする必要があります。
work-item 内では、操作は C++ コア言語で定義される関係の前に順序付けられた順番に従って行われます。
それぞれの work-item 間でメモリーの一貫性を維持するには、グループバリア操作、メモリーフェンスおよびアトミック操作を慎重に使用しなければなりません。異なる work-item 間で行われる操作の順番は、C++ コア言語で定義された関係の前に発生することで決定され、単一の関係ですべてのアドレス空間 (メモリー領域) を管理します。

第 3 章 SYCL アーキテクチャー | 29

SYCL 2020 リビジョン 6 - 3.8 メモリーモデル
すべての SYCL デバイス では、グループバリア操作を使用してローカルメモリーとグローバルメモリーを単一グループの work-item
間で一貫性を維持できます。取得-解放またはシーケンシャルな一貫性のあるメモリー操作をサポートする SYCL デバイスでは、メモリーフェンスおよびアトミック操作を使用して、一連の work-item で参照可能なすべてのメモリーをそのセット内の work-item 全体で一貫性を保つことができます。
ホストと SYCL デバイス、または同じコンテキスト内の異なる SYCL デバイス間のメモリーの一貫性は、3.9.8 節で定義されるように、
ホスト・アプリケーションの同期によって保証されます。USM 割り当てへの同時アトミックアクセスと取得-解放、またはシーケンシャルな一貫性のあるメモリー順序をサポートする SYCL デバイスでは、メモリーフェンスおよびアトミック操作を使用してデバイス間のメモ
リー一貫性を適用できます。

3.8.3.1. メモリー順序
1.

namespace sycl {2.
3.

enum class memory_order : /* 未定義 */ {4.

relaxed,5.

acquire,6.

release,7.

acq_rel,8.

seq_cst

9.

};

10.
11.

inline constexpr auto memory_order_relaxed = memory_order::relaxed;

12.

inline constexpr auto memory_order_acquire = memory_order::acquire;13.

inline constexpr auto memory_order_release = memory_order::release;14.

inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;

15.

inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;

16.
17.

} // namespace sycl

特定のアトミック操作のメモリー同期順序は、sycl::memory_order パラメーターによって制御されます。このパラメーターには次のいずれかを使用できます。

• sycl::memory_order::relaxed• sycl::memory_order::acquire• sycl::memory_order::release• sycl::memory_order::acq_rel• sycl::memory_order::seq_cst
これらの値の意味は、C++ コア言語で定義されるものと同じです。
メモリー順序の完全なセットがすべてのデバイスでサポートとされるとは限りません。また、コンテキスト内のデバイスのすべての組み
合 わせ が サ ポ ートさ れ る と も限 り ませ ん。 特定 のデ バ イスと コ ン テ キ スト で サ ポー トされ るメ モ リ ー 順 序は 、 sycl::device と
sycl::context クラスの機能を使用して照会できます。
SYCL 実装は、std::memory_order::consume と同じメモリー順序をサポートする必要はありませんが、SYCL デ
バイスカーネル内でこの順番を使用すると、未定義の動作となります。代わりに sycl::memory_order::acquire を使用することを推奨します。

30 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.8 メモリーモデル

3.8.3.2. メモリースコープ
1.

namespace sycl {2.
3.

enum class memory_scope : /* 未定義 */ {4.

work_item,

5.

sub_group,6.

work_group,7.

device,8.

system

9.

};

10.
11.

inline constexpr auto memory_scope_work_item = memory_scope::work_item;

12.

inline constexpr auto memory_scope_sub_group = memory_scope::sub_group;13.

inline constexpr auto memory_scope_work_group = memory_scope::work_group;14.

inline constexpr auto memory_scope_device = memory_scope::device;

15.

inline constexpr auto memory_scope_system = memory_scope::system;

16.
17.

} // namespace sycl指定されるアトミック操作によってメモリー順序の制約が適用される一連の work-item とデバイスは、sycl::memory_scope パラ
メーターによって制御されますが、このパラメーターの値は次のいずれかです。

• sycl::memory_scope::work_item: 順序の制約は、呼び出し元の work-item にのみ適用されます。
• sycl::memory_scope::sub_group: 順序の制約は、呼び出し元の work-item と同じ sub­group 内の work-item にのみ適用されます。

• sycl::memory_scope::work_group: 順序の制約は、呼び出し元の work-item と同じ work-group 内の work-item にのみ適用されます。

• sycl::memory_scope::device: 順序の制約は、呼び出し元の work-item と同じデバイスで実行される work-item にのみ適用されます。

• sycl::memory_scope::system: 順序の制約は、バッファーと USM の機能によって定義されるように、参照されるオブジェクトを含むメモリー割り当てへのアクセスが許可されるシステムのすべての work-item やホストスレッドに適用されます。
アトミック操作に適用できる最も広いスコープは、関連するメモリー位置にアクセスできる一連の work-item に相当します。例えば、
work-group のローカルメモリーのアトミック操作に適用可能な最も広いスコープは、sycl::memory_scope::work_group です。さらに広範囲のスコープが指定されると、関連するメモリー位置にアクセスできるすべての work-item を含む最も狭いスコープが指定されたかのように振る舞います。
C++ メモリーモデルにメモリースコープを追加すると、C++ コア言語の一部の定義が変更されます。例えば、データ
競合、同期との関係、およびシーケンシャルな一貫性は、OpenCL 2.0 仕様と同様の方法で、異なる (互換性はあります) スコープを持つアトミック操作を記述するように定義する必要があります。SYCL のメモリーモデルを形式化する取り組みが行われており、正式なメモリーモデルは SYCL 仕様の将来のバージョンに含まれる予定です。

3.8.3.3. アトミック操作
アトミック操作はバッファー内のメモリーと USM で実行できます。sycl::atomic_ref クラスを使用するバッファーへの安全なアトミッ
クアクセス、またはデバイスコードからの USM 割り当てを提供する必要があります。

第 3 章 SYCL アーキテクチャー | 31

SYCL 2020 リビジョン 6 - 3.9 SYCL プログラミング・モデル

3.8.3.4. フォワードプログレス (進行)
メモリーの一貫性を保証することは、フォワードプログレスの保証とは無関係です。SYCL の実装では、work-item を同時に実行する必要があるため、グループ内の work-item はグループバリアのセマンティクスに従うようにする必要がありますが、追加のフォワードプ
ログレスを保証する必要はありません。
メモリー操作をともなう work-item の同期は一般に安全とは言えませんが、次の条件が当てはまる場合にのみサポートされます。

• 取得-解放、またはシーケンシャルな一貫性があるメモリーの順序付けは、同期される一連の work-item を含むスコープでサポートされます。

• 同期される一連の work-item は相互に進行することが保証されます。
ほかの work-item に関係して進行する work-item の機能は、実装によって定義されます。

3.9. SYCL プログラミング・モデル
SYCL プログラムは標準 C++ で記述されます。ソースコードとデバイスコードは同じ C++ ソースファイル内に記述されるため、ホスト
コードからテンプレート化されたカーネルをインスタンス化でき、カーネルのソースコードをホストとデバイス間で共有することができます。デバイスカーネルは、カプセル化された C++ で呼び出し可能な形式 (operator() またはラムダ関数を持つ関数オブジェクト) であり、SYCL カーネルとしてコンパイルされるように指示されます。
SYCL プログラムのターゲットは異種システムです。カーネルは、異なるバイナリー表現で構成される異なるプロセッサー・アーキテク
チャー向けにコンパイルおよび最適化されます。

3.9.1. C++ 最小バージョン要件
SYCL で使用される C++ の機能は、特定の C++ バージョンをベースにしています。SYCL の実装は、最小の C++ バージョンをサポートする必要があり、これは、SYCL の機能定義 (ラムダなど) で利用できる C++ 構造を定義します。
SYCL 仕様の最小 C++ のバージョンは、3.3 節で定義される基準となる C++ コア言語によって決定されます。この仕様のすべての実装
は最低でもコア言語をサポートする必要があり、仕様における機能はコア言語の機能を基に定義されます。5.4 節で詳しく説明されていますが、SYCL カーネル関数内のコードまたは SYCL カーネル関数から呼び出されるコードのすべてのコア言語構造がサポートされるわけではないことに注意してください。
実際の実装では、SYCL で要求される最小バージョンよりも新しい C++ バージョンがサポートされることがあります。ただし、SYCL
要件よりも新しい機能を使用して記述されたコードは、同じ C++ バージョンをサポートしないほかの実装に移植できない可能性があります。

3.9.2. C++ の将来のバージョンとの整合性
SYCL の一部の実装は、3.3 節で定義されるように、今後の C++ 仕様に合わせて調整されています。
std::span、std::dynamic_extent、std::bit_cast の機能は SYCL 2020 で事前に採用されており、sycl:: 名前空間で利用できます。事前に採用されている機能の実装は、今後の C++ 仕様に準拠しており、将来の SYCL バージョンで標準 C++ の機能となる予定です。
SYCL 2020 の sycl::atomic_ref 機能は、今後の C++ 仕様に基づく構文を使用します。これらの機能は、SYCL 2020 の機能や異種プ
ログラミングとの互換性を維持するための変更を除き、C++ 仕様で説明されるように動作します。このような変更点は、この仕様の対応するセクション (節) に記載されています。

32 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.9 SYCL プログラミング・モデル

3.9.3. 基本データ並列カーネル
複数の work-item が実行され、ローカル同期を必要としないデータ並列カーネルは、sycl::range パラメーターによってパラメーター化された sycl::parallel_for 関数としてキューに投入されます。これらのカーネルは、指定されたレンジの work-item ごとにカーネル
関数のボディーを一度実行します。
グループバリアやローカルメモリーを含む、work-item のグループに対応付けられた機能は、これらのカーネル内で使用してはなりません。4.9.2 節で説明される機能を使用して、リダクション・セマンティクスを持つ変数を基本データ並列カーネルに追加できます。

3.9.4. ｗork-group データ並列カーネル
データ並列カーネルは、work-item がユーザー定義の次元の work-group に分割されるモードで実行することもできます。ユーザー
は、sycl::nd_range パラメーターを指定して sycl::parallel_for 関数のパラメーターとして、グローバルレンジとローカル・ワーク・サイ
ズを指定します。この実行モードでは、カーネルは指定されたサイズのワークグループの nd-range で実行されます。group_barrier 関
数を呼び出して、ローカルまたはグローバルメモリー内の同じ work-group 内の work-item 間でデータを共有し同期することができます。指定された parallel_for 内のすべての work-group は同じサイズであり、nd-range で定義されたグローバルサイズは、各次元がwork-group サイズの倍数であるか、グローバルサイズはゼロでなければなりません。グローバルサイズがゼロである場合、カーネル関数は実行されず、ローカルサイズは無視され、すべての依存関係が満たされます。
ｗork-group は sub-group に分割されることがあります。sub-group のサイズと数は実装によって定義され、カーネルごとに異なることがあります。さらに、デバイスが異なると work-group 内の sub-group のスケジュール方法が異なることがあります。カーネル内部の sub-group の work-item の最大数は、カーネルと使用する次元の組み合わせによって決定されます。ディスパッチされた subgroup のサイズは 1 から最大 sub-group の間であり、それぞれの sub-group のサイズはカーネル実行中に変化しません。workgroup と同様に、同一 sub-group 内の work-item は group_barrier 関数を呼び出すことで同期できます。
デバイス間での移植性を高めるため、開発者は、sub-group 内の work-item が特定の順番で実行されること、work-group が特定の方法で sub-group に分割されること、または work-group 内の 2 つの sub-group が相互に独立して進行することを想定してはなりません。
4.9.2 節で説明される機能を使用して、リダクション・セマンティクスを持つ変数を work-group のデータ並列カーネルに追加できます。

3.9.5. 階層データ並列カーネル
開発者と実装のフィードバックから、次に示す階層データの並列カーネルの機能は、モダン・プログラミングで普及しているフレームワークとパターンとの整合性を高めるため改善を続けています。これは SYCL API の重要な部分であり、今後変更されることが予測されるため、SYCL 仕様の今後のバージョンで新しい API が決定されるまで、新規のコードではこの機能を利用しないことを推奨します。もちろん、この機能を使用する既存のコードは、この仕様に準拠する実装によってサポートされます。

SYCL コンパイラーは、並列処理の階層的な性質を強調する構文を介して、work-group 内で実行されるデータ並列カーネルを指定する方法を提供します。このモードは純粋なコンパイラーの機能であり、カーネルの実行モデルに影響することはありません。
sycl::parallel_for を呼び出す代わりに、起動する work-group 数を示す sycl::range 値およびオプションのパフォーマンス・チューニ
ング向けにそれぞれの work-group サイズを示す 2 番目の sycl::range を指定して、sycl::parallel_for_work_group を呼び出します。
parallel_for_work_group スコープのすべてのコードは、work-group ごとに一度実行されます。parallel_for_work_group スコープ
内では、parallel_for_work_item を呼び出すことができます。これにより、現在の work-group のすべての work-item が実行される
新しいスコープが作成されます。プログラマーは、実行モデルの作用に厳密に一致するよう、外部 work-group ループ内に内部 workitem ループが存在するようなコードを記述できます。parallel_for_work_group スコープ内で宣言されるすべての変数は、workgroup のローカルメモリーに割り当てられますが、parallel_for_work_item スコープ内で宣言されるすべての変数は、プライベート・

第 3 章 SYCL アーキテクチャー | 33

SYCL 2020 リビジョン 6 - 3.9 SYCL プログラミング・モデル
メモリーに割り当てられます。与えられた parallel_for_work_group 実行内のすべての parallel_for_work_item 呼び出しは、同一次元を持つ必要があります。

3.9.6. 並列インスタンスから起動されないカーネル
カーネル関数で単一のインスタンスのみが実行される単純なカーネルは、sycl::single_task 関数でキューに投入されます。キューに投入されたカーネルは、work-item id パラメーターを受け取らずに一度だけ実行されます。これは、1 つの work-item で構成される単一の work-group を 1 つの計算ユニットで実行するカーネルと論理的に等価です。このようなカーネルは、複数のキューやデバイスに投入される可能性があり、それによりタスク並列方式で実行されます。

3.9.7. 事前定義カーネル
一部の SYCL バックエンドは、事前定義された機能をカーネルとしてユーザーに提供することがあります。そのようなカーネルはプロ
グラマブルではないため、SYCL C++ プログラミング・モデルの制限を受けず、記述方法は実装によって定義されます。

3.9.8. 同期
デバイス内で実行される処理要素の同期は、SYCL カーネル実行モデルに従って SYCL デバイスカーネルで処理されます。ホストメモ
リーで実行される SYCL デバイスカーネルの同期は、SYCL ランタイムを介して SYCL アプリケーションで行われます。

3.9.8.1. SYCL アプリケーションの同期
ホストとデバイス間の同期ポイントは次の操作で行います。

• バッファーの破棄: sycl::buffer、sycl::unsampled_image および sycl::sampled_image オブジェクトのデストラクターは、オブジェクトに送信されたすべてのワークが完了するのを待機し、データをホストメモリーにコピーしてから戻ります。これらのデスト
ラクターは、オブジェクトがホストメモリーにアタッチして作成され、データをホストにコピーしてからリターンする場合にのみ待機します。
バッファーを破棄するような複雑な同期は、shared_ptr や unique_ptr などほかの種類のメモリー参照を使用してバッファーを作成することで指定できます。

• ホストアクセサー: ホストアクセサーのコンストラクターは、キュー内の同一バッファー (またはイメージ) を更新するすべてのカーネルが完了するのを待機してから、コンストラクターがリターンする前にデータをホストメモリーにコピーします。表 6 に示すように、同じメモリー・オブジェクトへの要求を持つコマンドグループは、ホストアクセサーが破棄されるまで実行を開始できません。

• コマンドグループのキュー投入: SYCL ランタイムは、キューに投入されたコマンドグループの正しい動作を保証するため、キューに追加された正しいイベント依存関係があることを内部的に保証します。コマンドグループをキューに追加してもブロックされることはありません。代わりに、必要な同期がキューに追加され、sycl::event タイプのイベントが特定のコマンドグループに関連するイベント情報を含むキューの送信関数によって返されます。

• キュー操作: sycl::queue::wait() などのキュー操作を手動で使用することで、キューに送信されたすべてのコマンドグループの実行が完了するまで呼び出し元のスレッドの実行をブロックできます。この操作は、ほかのキュー内のコマンドグループとの依存関係にも影響することに注意してください。

• SYCL イベント・オブジェクト: SYCL は同期に利用できる sycl::event オブジェクトを提供します。異なる SYCL バックエンドのSYCL コンテキスト間で同期が必要な場合、SYCL ランタイムは、SYCL イベント・オブジェクトがコンテキスト間で正しく動作する
ように余分なホストベースの同期が追加されることを保証します。
ほかの SYCL オブジェクト (sycl::queue、sycl::context、…) のデストラクターは、ブロックしないことに注意してください。sycl::buffer、
sycl::sampled_image または sycl::unsampled_image デストラクターのみがブロックする可能性があります。この理論的な根拠とし

34 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.9 SYCL プログラミング・モデルて、ホストに影響しないオブジェクトは、パフォーマンスを損ねる可能性があるため破棄をブロックする必要がない、ということが言えます。従って、これが目的に合わない場合は、メンバー関数を使用して完了を待機するのはプログラマーの責任です。オブジェクトの存続期間に関する詳細は、3.9.12 節を参照してください。

3.9.8.2. SYCL カーネルの同期
SYCL では、同期はグローバルまたは work-item のグループ内でローカルのいずれかです。単一グループ内の work-item 間の同期
は、グループバリアによって行われます。
グループ内のすべての work-item は、バリアを超えて実行を継続する前に、バリアを実行する必要があります。グループバリアは、カー
ネルを実行するグループのすべての work-item が到達するか、もしくはまったく到達しない可能性があることに注意してください。
SYCL において、work-group バリアと sub-group バリア機能は、group_barrier 関数によって処理されます。
3.8.3 節で説明されるように、アトミック操作による異なる work-group 内の work-item 間の同期は、特殊な機能を備えた SYCL デバ
イスでのみ利用できます。

3.9.9. エラー処理
SYCL には、API が呼び出されたときに直ちに検出可能な同期エラーと、API 呼び出しがリターンした後でのみ検出できる非同期エ
ラーの 2 つのエラータイプあります。オブジェクトの作成失敗などの同期エラーは、例外をスローするランタイムによって直ちに報告されます。デバイスで実行中のカーネルで発生するエラーなどの非同期エラーは、非同期エラー・ハンドラー・メカニズムによって報告されます。
非同期エラーは発生してもすぐには報告されません。コンテキストまたはキューの非同期エラーハンドラーは、4.13.1.1 節と 4.13.1.2
節で説明される条件で、非同期に生成された例外オブジェクトのリストを含む sycl::exception_list オブジェクトを使用して呼び出されます。
4.13.1.2 節で説明されるように、ユーザーが非同期エラーハンドラーを指定したかどうかにかかわりなく、非同期エラーが発生することがあります。
一部の SYCL バックエンドは、ターゲット・プラットフォームに固有のエラー、または SYCL API で提供されるエラーよりも詳細なエラーを報告します。SYCL バックエンドによって報告されるエラーは、sycl::exception ベースから派生する必要があります。ユーザーが
SYCL バックエンドからスローされる詳しいエラーを取得するには、SYCL バックエンド固有のヘッダーをインクルードする必要があります。

3.9.10. フォールバックのメカニズム
コマンドグループ関数オブジェクトは、実行される単一のキュー、またはセカンダリー・キューのいずれかに送信できます。コマンドグ
ループ関数オブジェクトがプライマリー・キューへの投入に失敗すると、送信関数のパラメーターに指定されていればシステムはセカ
ンダリー・キューに投入することを試みます。コマンドグループ関数オブジェクトが両方のキューに投入されない場合、同期 SYCL 例外
がスローされます。
コマンドグループが正常にキューに投入されても、何らかの理由で非同期実行に失敗することがあります。その場合、ランタイムシステ
ムはプライマリー・キューではなくセカンダリー・キューでコマンドグループ関数オブジェクトを実行できることがあります。SYCL ラン
タイムが非同期フォールバックできるかどうかは、実装によって定義されます。

第 3 章 SYCL アーキテクチャー | 35

SYCL 2020 リビジョン 6 - 3.9 SYCL プログラミング・モデル

3.9.11. カーネルのスケジュールとデータ移動
コマンドグループ関数オブジェクトは、コマンドグループ handler への参照をパラメーターとして受け取ります。そのスコープ内のものは直ちに実行され、ハンドラー・オブジェクトをパラメーターとして受け取ります。これにより、ユーザーがスコープ内の SYCL 関数、メンバー関数、デストラクター、およびコンストラクターを呼び出して実行できます。これらの呼び出しはホスト上で非ブロッキングですが、コマンドグループが送信されるキューに操作を投入します。コマンド・グループ・スコープ内のすべてのユーザー関数は、コマンド
グループ関数オブジェクトが実行される際にホスト上で呼び出されますが、それらが呼び出すコマンドはすべて SYCL キューに追加されます。キューに追加されたすべてのコマンドは、データの依存関係に応じて順不同で実行されます。

3.9.12. オブジェクトの存続期間を管理
SYCL アプリケーションは、sycl::context オブジェクトが作成されるまで SYCL バックエンドを初期化しません。ユーザーは、
sycl::context オブジェクトを明示的に作成する必要はありませんが、sycl::queue オブジェクトは作成する必要があります。ユーザーが作成しないと sycl::context オブジェクトは暗黙的に作成されます。
SYCL オブジェクトにカプセル化されたすべての SYCL バックエンドは参照がカウントされ、すべての参照が解放されると破棄されます。ユーザーは SYCL バックエンド・オブジェクトを安全に初期化して解放するため、アプリケーションのライフタイム中に SYCL キュー(SYCL コンテキストを自動的に作成) を作成するだけで済みます。
SYCL 実装で必要とされるグローバル状態指定はありません。これは、例えば、ユーザーが共通コンテキストを明示的に構築することなく 2 つのキューを作成する場合、SYCL 実装では 2 つのキューの共有コンテキストを作成する必要がないことを意味します。SYCL 実
装は、パフォーマンスのためグローバルにコンテキストを共有またはキャッシュできますが、必須ではありません。
メモリー・オブジェクトは、アタッチされたホストメモリーの有無にかかわりなく構築できます。ホストメモリーがアタッチされていない
場合、そのメモリー・オブジェクトの破棄は非ブロッキングです。ユーザーは、C++ 標準ポインタークラスを使用して、ホストデータをユーザー・アプリケーションと共有し、バッファーとイメージのブロッキングまたは非ブロッキング動作を定義できます。ホストメモリー
が生のポインターを使用してアタッチされている場合、デフォルトの動作に従いますが、メモリー・オブジェクトを操作するコマンドグ
ループが完了するまでデストラクターがブロックし、メモリー・オブジェクトの内容がデバイスで変更された場合には、それらはホストにコピーされデストラクターはリターンします。
ホストメモリーが std::shared_ptr によりユーザー・アプリケーションと SYCL ランタイムで共有されている場合、std::shared_ptr の参照カウンターはバッファーを破棄する際にデータをコピーし戻す必要があるか判断するために使用されます。そして、コピーし戻す必要がある場合、ブロッキングまたは非ブロッキングであるかは、ユーザー・アプリケーションに依存します。
std::shared_ptr の代わりに、std::unique_ptr が用意されています。これは、関連するホストメモリーの初期化と利用にムーブ・セマン
ティクスを使用します。この場合、ユーザー・アプリケーションに関連するバッファーの動作は、破棄する際に非ブロッキングとなります。
3.9.8 節で説明するように、SYCL における唯一のブロッキング操作は以下です (明示的な待機を除く)。

• ホストアクセサーのコンストラクターは、作成前にキューに投入され、対応するオブジェクトへの書き込みが完了し、処理を続行
する前にホストメモリーに結果がコピーし戻されるカーネルを待機します。ホストアクセサーは、ユーザーが最初に指定した同一のホストメモリーにコピーし戻す必要はありません。

• ホストメモリーへコピーし戻す必要がある場合、またはホストメモリーがバッキングストアとして使用される場合、メモリー・オブジェクトは破棄されます。

3.9.13. デバイスの検出と選択
ユーザーは、コマンドグループ関数オブジェクトを送信するキューを指定し、それぞれのキューは、特定のデバイス (およびコンテキスト) で実行することが意図されています。ユーザーは、キューを作成する際にデバイスを直接指定することも、SYCL ランタイムがユー

36 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.10 メモリー・オブジェクト
ザーによって指定された設定を元にデバイスを選択するようにデバイスセレクターを使用することもできます。デバイスセレクターを指定すると、SYCL ランタイムがデバイスを検出することができます。SYCL デバイスセレクターがキューのコンストラクターに渡されるまで、デバイスの検出は行われません。デバイストポロジーは SYCL ランタイムでキャッシュされることがありますが、これは必須ではありません。
デバイスの検出は、サポートされるすべての SYCL バックエンドで提供されるすべてのプラットフォームのデバイスを返します。

3.9.14. SYCL バックエンド API とのインターフェイスSYCL アプリケーションを開発するには 2 つの方法があります。
1.

純粋な SYCL ジェネリック・アプリケーションを記述します。

2.

SYCL バックエンド固有の動作に依存する SYCL アプリケーションを記述します。

ユーザーが (1) に従う場合、SYCL アプリケーションのコンパイルや実行中にどの SYCL バックエンドが使用されるかは分かりません。
つまり、開発者が SYCL バックエンド API を利用することは想定されず、3.9 節で説明するように、標準 C++ タイプとのインターフェイ
スのみが利用可能であると想定されます。ユーザーが SYCL ジェネリック・アプリケーションを作成するには、<sycl/sycl.hpp> ヘッ
ダーをインクルードするだけで済みます。
一方、ユーザーが (2) に従う場合、使用する SYCL バックエンド API が判明している必要があります。この場合、ユーザーは SYCL バッ
クエンド API のプログラミングに必要なヘッダーを利用できると見なされます。ユーザーは <sycl/sycl.hpp> ヘッダーに加えて、4.3
節で定義される SYCL バックエンド固有のヘッダーをインクルードする必要があります。SYCL バックエンド固有のヘッダーは、SYCLAPI がネイティブ・バックエンド・オブジェクトと対話する相互運用インターフェイスを提供します。
相互運用インターフェイスは 4.5.1 節で説明します。

3.10. メモリー・オブジェクト
SYCL メモリー・オブジェクトは、SYCL ランタイムで処理されるデータを表し、単一または複数のデバイスの割り当てを表現できます。
バッファーとイメージのメモリー・オブジェクトには、キュー・オブジェクトが任意のデバイスのデータを利用できるように、1 つ以上のネ
イティブ・バックエンド・オブジェクトが含まれることがあります。SYCL 実装では、1 つのデバイスに対して複数のネイティブ・バックエンド・オブジェクトが含まれる場合があります。SYCL ランタイムは、システムで提供されるメカニズムを使用してネイティブ・バックエンド・オブジェクトのコピーを更新し、必要に応じてそれらのコピーが最新であるかを確認します。
実装の注意点
この更新では、利用可能な SYCL バックエンド固有のメカニズムを使用して、SYCL バックエンドからシステムメモ
リーにデータを転送し、新しい SYCL バックエンドのメカニズムにより別のデバイスにデータを転送します。
SYCL メモリー・オブジェクトは、バッファー・オブジェクトとイメージ・オブジェクトのいずれかに分類されます。バッファー・オブジェクト
は、C または C++ が配列を格納するのと同じ方法で、リニアに連続して配置される 1 次元、2 次元、または 3 次元の要素の集合を格納します。イメージ・オブジェクトは、1 次元、2 次元、または 3 次元のテクスチャー、フレームバッファー、およびイメージを格納します。これらのデータは、最適化されたデバイス固有の形式でメモリーに格納され、特殊な方法でアクセスする必要があります。
バッファー・オブジェクトの要素は、スカラー・データ・タイプ (int または float など)、ベクトル・データ・タイプ、またはユーザー定義の構
造体にできます。SYCL では、バッファー・オブジェクトはテンプレート・タイプ (sycl::buffer) であり、要素タイプと次元数によってパラメーター化されます。イメージ・オブジェクトは、限定された形式で保存されます。イメージ・オブジェクトの要素は、SYCL バックエンド
実 装 で 提 供 さ れ る 事 前 定 義 イ メ ー ジ 形 式 の リ ス ト か ら 選 択 さ れ ま す 。 イ メ ー ジ は sycl::unsampled_image ま た は
sycl::sampled_image タイプでカプセル化されます。イメージ・オブジェクト要素の最小数は 1 であり、バッファー・オブジェクト要素の最小数はゼロです。

第 3 章 SYCL アーキテクチャー | 37

SYCL 2020 リビジョン 6 - 3.11 多次元オブジェクトと線形化
バッファーとイメージ・オブジェクトの基本的な違いは以下です。

• バッファー内の要素は、1、2、または 3 次元の配列に格納され、デバイスで実行されるカーネルでアクセサーを使用してアクセスできます。カーネルのアクセサーは、C++ ポインタータイプを取得するメンバー関数または sycl::global_ptr クラスを提供します。

• イメージの要素は、ユーザーには不透過で、ポインターでは直接アクセスできない形式で保存されます。SYCL は、カーネルがイメージの読み取りまたは書き込みを行うイメージアクセサーとサンプラーを提供します。

• バッファー・オブジェクトは、データがメモリーに格納されるのと同じ形式でカーネル内でアクセスされますが、イメージ・オブジェ
クトは、必ずしもデータがメモリーに格納される形式でカーネル内でアクセスされるとは限りません。

• イメージ要素は、カーネル内で常に 4 コンポーネントのベクトルです (それぞれのコンポーネントは float または符号あり/符号な
し整数にできます)。イメージを読み取るアクセサーは、イメージ要素をストレージ形式から 4 コンポーネントのベクトルに変換します。同様に、イメージに書き込む SYCL アクセサーのメンバー関数は、イメージ要素を 4 コンポーネントのベクトルから、適切なイメージ形式に変換します (例えば、4 つの 8 ビット要素)。
場合によっては、ユーザーは、SYCL イメージまたはバッファー・オブジェクトの同期、メモリー管理、およびストレージ・セマンティクスを細かく制御する必要があります。例えば、ユーザーが使用するメモリー・オブジェクトのホストメモリーを指定して、メモリー・オブジェク
トを破棄する際にブロックされないようにします。
SYCL アプリケーションの制御と利用例に応じて、C++ クラスとパターンを使用し、参照をカウントすることでユーザー・アプリケーショ
ンと SYCL ランタイム間でデータを共有できます。ホストでのメモリー割り当て制御、およびホストとデバイスのメモリー間のマッピン
グでは、事前定義またはユーザー定義の C++ std::allocator クラスが使用されます。データを共有する SYCL アプリケーションと非SYCL アプリケーション間の同期を適切に制御するため、std::shared_ptr と std::mutex クラスが使用されます。

3.11. 多次元オブジェクトと線形化
SYCL は、バッファーやアクセサーなど多次元オブジェクトを定義します。カーネル内の work-item の反復空間も多次元である可能性があります。それぞれの次元のサイズは、1、2、または 3 次元の range オブジェクトによって定義され、多次元空間の要素は対応する
range と同じ次元数の id オブジェクトで識別できます。
いずれかの次元サイズがゼロである場合、多次元レンジの要素はゼロになります。

3.11.1. 線形化
一部の多次元オブジェクトはリニア形式になります。その場合、オブジェクトのレンジの右端の項目が線形化で最も早く変化します。
レンジ range{r0, r1, r2} の 3 次元オブジェクト内の 3 次元要素 id{id0, id1, id2} は、次のように定義されるリニア位置を持ちます。

2 次元 range{r0, r1} 内の 2 次元要素 id{id0, id1} は、同様の式に従います。

1 次元レンジ range{r0} 内の 1 次元要素 id{id0} は、そのリニア形式と同等です。

3.11.2. 多次元のインデックス操作
一部の多次元オブジェクトは、連続する添字オペレーターがそれぞれの次元に対応する添字オペレーターを使用してインデックスを付加することができます。右端のオペレーターは、標準 C++ 配列と同様に最も早く変化します。形式的には、3 次元添字アクセス

38 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.12 実装オプション
a[id0][id1][id2] は、id{id0, id1, id2} の要素を参照します。2 次元添字アクセス a[id0][id1][id2] では、id{ id1, id2} の要素を参照します。また、1 次元添字アクセス a[id2] は、id{ id2} の要素を参照します。

3.12. 実装オプション
SYCL 言語は、柔軟性のある実装を可能にするように設計されています。ここで説明する内容は規範的ではないため、実装はここに示すガイドラインに従う必要はありませんが、SYCL の実装に利用可能な方針をユーザーが理解できるようにすることを目的としています。

3.12.1. 単一ソース複数コンパイラー
SMCP として知られるこの手法では、ホスト・コンパイラーとデバイス・コンパイラーが別々になっています。SYCL ソースファイルは、ホスト・コンパイラーとデバイス・コンパイラーによって 2 回コンパイルされます。実装は複数のデバイス・コンパイラーをサポートできま
すが、その場合それぞれの SYCL ソースファイルは 2 回以上コンパイルされます。この手法では、ホスト・コンパイラーは SYCL に対応
しない既存のコンパイラーであってもかまいませんが、デバイス・コンパイラーは SYCL に対応している必要があります。デバイス・コン
パイラーは、ソースファイルを解析して SYCL カーネル関数とそれが呼び出すデバイス関数を識別します。SYCL はこの解析を静的に行えるように設計されています。デバイス・コンパイラーは、SYCL カーネル関数とデバイス関数のコードのみを生成します。
通常、デバイス・コンパイラーは、ホスト・コンパイラーと SYCL ランタイム間のインターフェイスとなるヘッダーファイルを生成します。
デバイス・コンパイラーが最初に実行され、次にホスト・コンパイラーがホストコードの生成時にヘッダーファイルを参照します。
この手法のデバイス・コンパイラーは、SYCL カーネル関数から 1 つ以上のデバイスイメージを生成します。これは、SYCL ランタイムで読み取ることができます。それぞれのデバイスイメージには、デバイスのネイティブ ISA を含めることも、SPIR-V などの中間言語を含めることもできます。後者では、SYCL カーネル関数がデバイスに送信される際に SYCL ランタイムが中間言語をネイティブ ISA に変換する必要があります。
この手法では、ホスト・コンパイラーとデバイス・コンパイラーが別であるため、SYCL カーネル関数 (デバイス・コンパイラーによってコンパイルされる) を、それを呼び出すコード (ホスト・コンパイラーでコンパイルされる) と関連付ける必要があります。縮小機能セット (B.2
節) に準拠する実装では、SYCL カーネル関数の C++ タイプを使用してこれを実現できます。このタイプは、SYCL カーネル関数がラムダ関数の場合はカーネル名テンプレート・パラメーターによって指定され、SYCL カーネル関数がオブジェクトの場合はクラスタイプから取得されます。完全な機能セット (B.1 節) に準拠する実装では、呼び出しサイトでカーネル名を必要としないため、関連付けのためほかの方法を実装する必要があります。

3.12.2. 単一ソース単一コンパイラー
この方法では、ベンダーはそれぞれの SYCL ソースファイル一度だけ読み込むカスタム・コンパイラーを実装し、そのコンパイラーがSYCL カーネル関数のホストコードとデバイスイメージを生成します。SMCP と同様に、それぞれのデバイスイメージには、ネイティブデ
バイス ISA または中間コードのどちらかを含めることができます。

3.12.3. ライブラリーのみの実装
SYCL をサポートしない既存のコンパイラーを使用するため、SYCL をライブラリーとして実装することも可能です。そのような実装では、それぞれのカーネルはホストシステムで実行されることもあります。

第 3 章 SYCL アーキテクチャー | 39

SYCL 2020 リビジョン 6 - 3.13 カーネルの言語制限

3.13. カーネルの言語制限
SYCL カーネルは SYCL デバイスで実行されますが、SYCL カーネルから呼び出されるすべての関数は、SYCL デバイス・コンパイラー
によってデバイス向けにコンパイルされます。SYCL カーネルが実行される異種デバイスの制限から、カーネルコードで使用できる基本
C++ 言語機能には特定の制限が生じます。言語制限の詳細については 5.4 節を参照してください。
SYCL カーネルは、コマンド・グループ・スコープの値によって取得されるか、アクセサーを使用してホストからデバイスに渡される引数から取得されます。ホストとデバイスコード間でデータ構造を共有すると、デバイスコピー可能なオブジェクトのみが使用できるなど、特定の制限が課せられます。通常、ホスト向けに初期化されたポインターをデバイスで利用することはできません。 sycl::buffer、
sycl::unsampled_image、および sycl::sampled_image などの SYCL メモリー・オブジェクトは、カーネルに渡すことができません。代
わりに、カーネルはアクセサーを介してオブジェクトと対話する必要があります。これらのメモリー・オブジェクト・クラスの階層構造はサポートされず、ほかのデータコンテナーは SYCL インターフェイスを使用して SYCL データ管理クラスに変換しなければなりません。
カーネル・パラメーター受け渡しの規則の詳細については、4.12.4 節を参照してください。
USM 割り当てへのポインターは、引数として直接、もしくはほかのオブジェクト内で間接的にカーネルに渡すことができます。カーネル
引数として渡される USM 割り当てへのポインターは、グローバルアドレス空間にあるものとして扱われます。

3.13.1. コピー可能なデバイス
SYCL 実装では、ホストとデバイス間、または 2 つのデバイス間でデータのコピーが必要になる場合があります。例えば、コマンドグ
ループがバッファーの内容に関する要件を持つ場合、またはアプリケーションが特定の引数を SYCL カーネル関数に渡す際に発生することがあります (4.12.4 節で説明します)。そのようなデータは、次に定義するようにデバイスコピー可能なタイプでなければなりま
せん。
(C++ コア言語で定義されているように) 単純にコピーできるタイプは暗黙的にデバイスでコピーできます。さらに、C++ コア言語における次のタイプは、暗黙的にデバイスでコピーできます。

• std::array<T, 0>• std::array<T, N> (T デバイスコピー可能な場合)• std::optional<T> (T デバイスコピー可能な場合)• std::pair<T1, T2> (T1 と T2 がデバイスコピー可能な場合)• std::tuple<>• std::tuple<Types...> パラメーター・パック Types のすべてのタイプがデバイスコピー可能な場合• std::variant<>• std::variant<Types...> パラメーター・パック Types のすべてのタイプがデバイスコピー可能な場合• std::basic_string_view<CharT, traits>• std::span<ElementType, Extent> (std::span タイプは C++20 で導入されました)
std::basic_string_view<CharT, traits> と std::span<ElementType, Extent> タイプは、ビュータイプであり、タイ
プに含まれないデータを参照します。これらのビュータイプはデバイスコピー可能ですが、実装はデバイス間でコピーを行う際に、データではなくビューのみをコピーします。コピー後にデータを参照するには、アプリケーションはホストとデバイス (またはデバイス間でコピーする場合は両方のデバイス) でアクセス可能な統合共有メモリー(USM) にあるデータを割り当てる必要があります。
また、実装によっては、アプリケーションが特定のクラスタイプをデバイスコピー可能であるとして明示的に宣言できる場合があります。
実装がこの機能をサポートする場合、プリプロセッサー・マクロ SYCL_DEVICE_COPYABLE を 1 に定義する必要があります。サポー

40 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.14 エンディアンのサポート
トしない場合は、このプリプロセッサー・マクロを定義してはなりません。実装がこの機能をサポートする場合、次のすべてが当てはまる
場合にクラスタイプ T はデバイスコピー可能です。

• アプリケーションが is_device_copyable_v<T> 特性を true に定義。
• タイプ T には、少なくとも 1 つのコピー・コンストラクター、ムーブ・コンストラクター、コピー代入オペレーター、またはムーブ代入
オペレーターがあります。

• コピー・コンストラクター、ムーブ・コンストラクター、コピー代入オペレーター、またはムーブ代入オペレーターは public です。
• デバイス間でタイプ T のオブジェクト転送を行う場合、コピー・コンストラクター、ムーブ・コンストラクター、コピー割り当てオペ
レーター、またはムーブ割り当てオペレーターはオブジェクトのビット単位のコピーに相当します。

• タイプ T には public の非削除デストラクターがあります。
デストラクターはデバイスで実行しても効果はありません。アプリケーションがクラスタイプをデバイスコピー可能であると明示的に宣言する場合、そのタイプの配列やタイプの cv 修飾されたバージョンもデバイスにコピーできます。
デバイス間でコピーを行う際に、実装が is_device_copyable_v として宣言されるクラスのコピー・コンストラク
ター、ムーブ・コンストラクター、コピー代入オペレーター、またはムーブ代入オペレーターを実際に呼び出すかどうかは未定義です。これらの操作はビット単位のコピーと同じでなければならず、実装ではオブジェクトが格納されるメモリーを単純にコピーすることがあります。同様に、デストラクターは、デバイスに影響してはならないため、実装が実際にデバイスでそのようなクラスのデストラクターを呼び出すかどうかは未定義です。

3.14. エンディアンのサポート
SYCL は特定のバイトオーダーを義務付けていませんが、ホストのバイトオーダーは常にデバイスのバイトオーダーと一致します。これにより、バイトスワップを行うことなくホストとデバイス間でデータをコピーできます。

3.15. SYCL アプリケーションの例
以下の例は、前述の機能を組み合わせた複雑なアプリケーションのサンプルです。
1.

#include <iostream>2.

#include <sycl/sycl.hpp>

3.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::" は必要ありません

4.
5.

// 行列のサイズ

6.

constexpr size_t N = 2000;

7.

constexpr size_t M = 3000;

8.
9.

int main() {10.

// 作業するキューを作成

11.

queue myQueue;

12.
13.

// 行列用に float の 2D バッファーを作成

14.

buffer<float, 2> a { range<2>{N, M} };15.

buffer<float, 2> b { range<2>{N, M} };16.

buffer<float, 2> c { range<2>{N, M} };

17.
18.

// 初期化のため非同期カーネルを起動

19.

myQueue.submit([&](handler& cgh) {20.

// カーネルは書き込みを行うため、書き込みアクセサーを取得

第 3 章 SYCL アーキテクチャー | 41

SYCL 2020 リビジョン 6 - 3.15 SYCL アプリケーションの例
21.

accessor A { a, cgh, write_only

};

22.
23.

// N*M 2D 反復空間で反復する並列カーネルをキューに投入

24.

cgh.parallel_for(range<2> {N, M},

25.
26.

[=](id<2> index) { A[index] = index[0] * 2 + index[1]; });
});

27.
28.

// 非同期カーネルを起動して b を初期化

29.

myQueue.submit([&](handler& cgh) {30.

// カーネルは b に書き込みを行うため、書き込みアクセサーを取得

31.

accessor B { b, cgh, write_only

};

32.
33.

// 上記のアクセスパターンから SYCL ランタイムは、

34.

// この command_group が最初のコマンドとは独立しており、

35.

// 独立してスケジュールできることを確認

36.
37.

// N*M 2D 反復空間で反復する並列カーネルをキューに投入

38.

cgh.parallel_for(range<2> {N, M}, [=](id<2> index) {39.

B[index] = index[0] * 2014 + index[1] * 42;

40.
41.

});
});

42.
43.

// 非同期カーネルを起動して、行列の加算を計算します c = a + b

44.

myQueue.submit([&](handler& cgh) {45.

// カーネル内で a と b は読み取りで c は書き込みです46.

accessor A { a, cgh, read_only };47.

accessor B { b, cgh, read_only };48.

accessor C { c, cgh, write_only };

49.
50.

// これらのアクセサーから、SYCL ランタイムはこのカーネルが実行されると51.

// a と b を計算するカーネルが完了したことを確認します

52.
53.

// N*M 2D 反復空間で反復する並列カーネルをキューに投入

54.

cgh.parallel_for(range<2> {N, M},

55.
56.

[=](id<2> index) { C[index] = A[index] + B[index]; });
});

57.
58.

// アプリケーションのスコープから c を読み取るアクセサーを要求します59.

// SYCL ランタイム はコンストラクターから戻る前に c の準備ができるのを待機します60.

host_accessor C { c, read_only };61.

std::cout << std::endl << "Result:" << std::endl;

62.

for (size_t i = 0; i < N; i++) {63.

for (size_t j = 0; j < M; j++) {64.

// 結果を解析値と比較します65.

if (C[i][j] != i * (2 + 2014) + j * (1 + 42)) {66.

std::cout << "Wrong value " << C[i][j] << " on element " << i << " "67.

<< j << std::endl;

68.

exit(-1);

69.

}

70.
71.

}
}

72.

42 | 第 3 章 SYCL アーキテクチャーSYCL 2020 リビジョン 6 - 3.15 SYCL アプリケーションの例
73.

std::cout << "Good computation!" << std::endl;

74.
75.

return 0;}

第 3 章 SYCL アーキテクチャー | 43

SYCL 2020 リビジョン 6 - 4.1 バックエンド

第 4 章 SYCL プログラミング・インターフェイスSYCL プログラミング・インターフェイスは、1 つ以上の SYCL バックエンド API 向けに共通の抽象化機能セットを提供します。ここでは、これらの SYCL バックエンド間で実行される SYCL ランタイムへの C++ ライブラリー・インターフェイスについて説明します。
ここで定義する SYCL インターフェイス全体は、特定の SYCL バックエンドにかかわりなく、このドキュメントの一般的な用語で説明される相互運用性インターフェイスを除き、すべての SYCL バックエンドで利用できなければなりません。
SYCL は、SYCL クラスのすべてのメンバー関数と特殊メンバー関数がスレッドセーフであることを保証しています。
この仕様で定義されるすべての列挙型のベースとなるタイプは、実装で定義されます。また、列挙型のすべての列挙子は、列挙子の値が仕様で明示的に示されていない限り、実装で定義された一意の値を持ちます。

4.1. バックエンド
SYCL 実装で利用可能な SYCL バックエンドは enum class backend で識別できます。
1.

namespace sycl {2.

enum class backend ： /* 未定義 */ {3.

/* 以下参照 */

4.

};

5.

} // namespace sycl

enum class backend は実装で定義されており、SYCL 実装がサポートする SYCL バックエンドごとに一意の識別子を与える必要があります。
enum class backend に列挙されるそれぞれの名前付き SYCL バックエンドは、SYCL バックエンド仕様に関連付けられている必要があります。この仕様の多くのセクションでは、関連付けられている SYCL バックエンド仕様を参照します。

4.1.1. バックエンド・マクロ
enum class backend で定義される識別子は実装定義であり、SYCL 実装では識別子ごとにプリプロセッサー・マクロも用意する必要があります。SYCL バックエンドが Khronos SYCL group で定義される場合、マクロ名は SYCL_BACKEND_<backend_name> となります。バックエンド名はすべて大文字で、backend_name に関連する識別子です。Khronos SYCL group 外部のベンダーが SYCL バッ
クエンドを定義する場合のマクロ名については、6 章を参照してください。

4.2. ジェネリック vs 非ジェネリック SYCLSYCL プログラミング API は、ジェネリック SYCL と非ジェネリック SYCL の 2 つのカテゴリーに分かれています。SYCL プログラミン
グ API の大部分がジェネリック SYCL であると見なされます。ただし、enum class backend は非ジェネリック SYCL であると見なされ、
backend で定義される識別子は実装定義であるため、SYCL バックエンドの特殊化されたコードパスでのみ利用する必要があります。
backend 列挙型クラスが利用される非ジェネリック SYCL アプリケーションでは、SYCL 実装がその SYCL バックエンドの特殊化をサポートしていなくても SYCL アプリケーションがコンパイルできるよう、関連するプリプロセッサー・マクロと #ifdef 文を使用してコードを保護する必要があります。

44 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.3 ヘッダーファイルと名前空間

4.3. ヘッダーファイルと名前空間
SYCL は標準ヘッダーファイル <sycl/sycl.hpp> を提供します。このヘッダーファイルは、SYCL プログラミング API を使用するすべてのコンパイル単位でインクルードする必要があります。
この仕様で定義されるすべての SYCL クラス、定数、タイプ、および関数は、::sycl 名前空間になければなりません。
SYCL 1.2.1 との互換性を維持するため、SYCL には別の標準ヘッダーファイルがあります。<CL/sycl.hpp> は、<sycl/sycl.hpp> の代わりにインクルードできます。この仕様で定義されるすべての SYCL クラス、定数、タイプ、および関数は、::cl::sycl C++ 名前空間になければなりません。
一貫性を保つため、プログラミング API は <sycl/sycl.hpp> ヘッダーと ::sycl 名前空間のみを参照しますが、これは SYCL 1.2.1 ヘッ
ダーおよび名前空間と同義であると見なす必要があります。
“sycl/ext/” と “sycl/backend/” で始まるインクルード・パスは、それぞれ SYCL 拡張とバックエンド相互運用ヘッダー向けに予約されています。その他のインクルード・パスは、“sycl/” で始まり sycl::detail 名前空間は実装向けに予約されています。
SYCL バックエンドが Khronos SYCL group によって定義される場合、SYCL バックエンドの機能は “sycl/backend/<backend_name>.hpp”
ヘッダーを介して利用でき、 SYCL バ ッ ク エ ン ド 固有のすべての機能は sycl::<backend_name> 名前空間にあります。ここで、<backend_name> は SYCL バックエンド仕様で定義される SYCL バックエンドの名前です。
6 章では、Khronos SYCL group 以外のベンダーが定義する SYCL バックエンドを含む、ベンダーが提供する拡張機能で許可される
ヘッダーファイルと名前空間を定義します。
特に指定されない限り、SYCL プログラムの動作は、namespace sycl または namespace sycl 内の名前空間にエンティティーを追加すると未定義となります。

4.4. 利用可能なクラス
SYCL では SYCL アプリケーションが利用可能な SYCL ランタイムクラスが提供され、それらには SYCL カーネル関数で利用できるもの、またカーネル関数とアプリケーションの両方で利用できるものがあり、SYCL カーネル関数に引数として渡すことができます。
次の SYCL ランタイムクラスは、ホスト・アプリケーションで利用可能でなければなりません： buffer、buffer_allocator、context、device、
device_image、event、exception、handler、host_accessor、host_sampled_image_accessor、host_unsampled_image_accessor、id、
image_allocator、kernel、kernel_id、marray、kernel_bundle、nd_range、platform、queue、range、sampled_image、image_sampler、
stream、unsampled_image、vec。
次の SYCL ランタイムクラスは、SYCL カーネル関数で利用できる必要があります: accessor、atomic_ref、device_event、group、
h_item、id、item、local_accessor、marray、multi_ptr、nd_item、range、reducer、sampled_image_accessor、stream、sub_group、
unsampled_image_accessor、vec。

4.5. 共通インターフェイス
次元テンプレート・パラメーターが SYCL クラスで使用される場合、ほとんどのケースでデフォルトは 1 次元となります。

第 4 章 SYCL プログラミング・インターフェイス | 45

SYCL 2020 リビジョン 6 - 4.5 共通インターフェイス

4.5.1. バックエンドの相互運用性
多くの SYCL ランタイムクラスは、クラスのベースとなる SYCL バックエンドに固有のオブジェクトをカプセル化するように実装されます。状況に応じて、これらのクラスは SYCL と関連する SYCL バックエンド間のアプリケーション内の相互運用性をサポートするため、
SYCL ランタイム・オブジェクトとネイティブ・バックエンド・オブジェクト間のインターフェイスを提供することがあります。
SYCL ランタイムクラスとの相互運用性には、SYCL バックエンド API による SYCL アプリケーション上での相互運用性、SYCL バック
エンドの同等のカーネル言語タイプによる SYCL カーネル関数内での相互運用性、および interop_handle によるホストタスク内での相互運用性の 3 つがあります。
SYCL アプリケーションの相互運用性、SYCL カーネル関数の相互運用性は、およびホストタスクの相互運用性は、異なるインターフェ
イスを介して提供され、同じ SYCL オブジェクトに対し異なる動作を提供することがあります。
SYCL アプリケーションの相互運用性は、buffer、context、device、device_image、event、kernel、kernel_bundle、platform、
queue、sampled_image、および unsampled_image 向けに提供される場合があります。
SYCL カーネル関数の相互運用性は、カーネルスコープ内でのみ accessor、device_event、local_accessor、sampled_image_accessor、
stream、および unsampled_image_accessor に提供され、スコープ外では使用できない場合があります。
ホストタスクの相互運用性は、ホストタスク・スコープ内の accessor、sampled_image_accessor、unsampled_image_accessor、
queue、device、[code]#context に対してのみ提供されます (4.10 節を参照)。
SYCL バックエンドの相互運用性のサポートはオプションであるため、SYCL 実装で提供する必要はありません。SYCL バックエンドの相互運用性を使用する SYCL アプリケーションは、非ジェネリック SYCL と見なされます。
使用する SYCL バックエンドの相互運用性の詳細は、その SYCL バックエンドの SYCL バックエンド仕様に記載されます。

4.5.1.1. タイプ特性 backend_traits
1.

namespace sycl {2.
3.

template <backend Backend> class backend_traits {4.

public:5.

template <class T> using input_type = /* see-below */;6.
7.

template <class T> using return_type = /* see-below */;

8.
9.
10.

using errc = /* see-below */;
};

11.
12.

template <backend Backend, typename SyclType>13.

using backend_input_t =14.

typename backend_traits<Backend>::template input_type<SyclType>;

15.
16.

template <backend Backend, typename SyclType>17.

using backend_return_t =18.

typename backend_traits<Backend>::template return_type<SyclType>;

19.
20.

} // namespace sycl

backend_traits クラスで定義される SYCL バックエンドの相互運用性には、一連のタイプ特性が用意されています。

46 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.5 共通インターフェイス
列挙型クラス backend に列挙される名前付き SYCL バックエンドごとに、backend_traits の特殊化を提供する必要があります。

• SYCL バックエンドと SYCL アプリケーションとの相互運用性をサポートする SYCL ランタイムクラス T ごとに、input_type の特殊化は SYCL バックエンド仕様で指定される SYCL バックエンドの T に関連付けられた SYCL アプリケーションの相互運用性ネ
イティブ・バックエンド・オブジェクトのタイプとして定義する必要があります。input_type は、バックエンド固有のネイティブ・オブ
ジェクトから SYCL オブジェクトを生成する際に使用されます。詳しくは、関連するバックエンドの仕様を参照してください。

• SYCL バックエンドと SYCL アプリケーションの相互運用性をサポートする SYCL ランタイムクラス T ごとに、戻り値の特殊化を
SYCL バックエンド仕様で指定される SYCL バックエンドの T に関連付けられたSYCL アプリケーションの相互運用性ネイティ
ブ・バックエンド・オブジェクトのタイプとして定義する必要があります。return_type は、SYCL オブジェクトから SYCL バックエ
ンド固有のネイティブ・オブジェクトを取得する際に使用します。詳しくは、関連するバックエンドの仕様を参照してください。

• SYCL バックエンドとカーネル関数の相互運用性をサポートする SYCL ランタイムクラス T ごとに、backend_traits 内のreturn_type の特殊化は、SYCL バックエンド仕様で指定される SYCL バックエンドの T に関連付けられたカーネス関数の相互運用性ネイティブ・バックエンド・オブジェクトのタイプとして定義する必要があります。詳しくは、関連するバックエンドの仕様を参照してください。

• errc の特殊化は、SYCL バックエンドのエラー・コード・タイプとして定義します。
タイプエイリアス backend_input_t は、タイプ T の特定の SYCL オブジェクトの backend_traits 内の input_type タイプとreturn_type タイプへの冗長でないアクセスを可能にします。

4.5.1.2. テンプレート関数 get_native1.

namespace sycl {2.
3.

template<backend Backend, class T>

4.

backend_return_t<Backend, T> get_native(const T& syclObject);5.
6.

} // namespace sycl

SYCL アプリケーションの相互運用性をサポートする SYCL ランタイムクラス T ごとに、get_native の特殊化を定義する必要があります。これは、T のインスタンスを取得し、SYCL アプリケーションの相互運用性に利用できる syclObject に関連付けられた SYCL アプ
リケーションの相互運用性ネイティブ・バックエンド・オブジェクトを返します。リターンされるオブジェクトのライフタイムはバックエンド定義であり、バックエンド仕様で定義されます。
カーネル関数の相互運用性をサポートする SYCL ランタイムクラス T ごとに、get_native の特殊化を定義する必要があります。これは、T のインスタンスを取得し、カーネル関数の相互運用性に利用できる syclObject に関連付けられたカーネル関数の相互運用性ネ
イティブ・バックエンド・オブジェクトを返します。これらのテンプレート関数の可用性と動作は、SYCL バックエンド仕様のドキュメントで定義されています。
SYCL オブジェクトのバックエンドがターゲットのバックエンドと一致しない場合、get_native 関数は errc::backend_mismatch エ
ラーコードの例外をスローする必要があります。

4.5.1.3. テンプレート関数 make_*1.

namespace sycl {2.
3.

template<backend Backend>

4.

platform make_platform(const backend_input_t<Backend, platform>& backendObject);5.
6.

template<backend Backend>

7.

device make_device(const backend_input_t<Backend, device>& backendObject);

第 4 章 SYCL プログラミング・インターフェイス | 47

SYCL 2020 リビジョン 6 - 4.5 共通インターフェイス
8.
9.

template<backend Backend>

10.

context make_context(const backend_input_t<Backend, context>& backendObject,

11.

const async_handler asyncHandler = {});

12.
13.

template<backend Backend>

14.

queue make_queue(const backend_input_t<Backend, queue>& backendObject,

15.

const context& targetContext,

16.

const async_handler asyncHandler = {});

17.
18.

template<backend Backend>

19.

event make_event(const backend_input_t<Backend, event>& backendObject,

20.

const context& targetContext);

21.
22.
23.

template <backend Backend, typename T, int Dimensions = 1,
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>24.

buffer<T, Dimensions, AllocatorT>25.

make_buffer(const backend_input_t<Backend, buffer<T, Dimensions, AllocatorT>>&

26.
27.

backendObject,
const context& targetContext, event availableEvent);

28.
29.
30.

template <backend Backend, typename T, int Dimensions = 1,
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>31.

buffer<T, Dimensions, AllocatorT>32.

make_buffer(const backend_input_t<Backend, buffer<T, Dimensions, AllocatorT>>&

33.
34.

backendObject,
const context& targetContext);

35.
36.

template <backend Backend, int Dimensions = 1,

37.

typename AllocatorT = sycl::image_allocator>

38.

sampled_image<Dimensions, AllocatorT> make_sampled_image(

39.
40.

const backend_input_t<Backend, sampled_image<Dimensions, AllocatorT>>&
backendObject,

41.

const context& targetContext, image_sampler imageSampler,

42.

event availableEvent);

43.
44.

template <backend Backend, int Dimensions = 1,

45.

typename AllocatorT = sycl::image_allocator>

46.

sampled_image<Dimensions, AllocatorT> make_sampled_image(

47.
48.
49.

const backend_input_t<Backend, sampled_image<Dimensions, AllocatorT>>&
backendObject,
const context& targetContext, image_sampler imageSampler);

50.
51.
52.
53.
54.
55.
56.

template <backend Backend, int Dimensions = 1,
typename AllocatorT = sycl::image_allocator>
unsampled_image<Dimensions, AllocatorT> make_unsampled_image(
const backend_input_t<Backend, unsampled_image<Dimensions, AllocatorT>>&
backendObject,
const context& targetContext, event availableEvent);

57.
58.
59.

template <backend Backend, int Dimensions = 1,
typename AllocatorT = sycl::image_allocator>

48 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.5 共通インターフェイス
60.
61.

unsampled_image<Dimensions, AllocatorT> make_unsampled_image(
const backend_input_t<Backend, unsampled_image<Dimensions, AllocatorT>>&

62.
63.

backendObject,
const context& targetContext);

64.
65.

template<backend Backend, bundle_state State>

66.

kernel_bundle<State> make_kernel_bundle(

67.

const backend_input_t<Backend, kernel_bundle<State>>& backendObject,

68.

const context& targetContext);

69.
70.

template<backend Backend>71.

kernel make_kernel(const backend_input_t<Backend, kernel>& backendObject,

72.

const context& targetContext);

73.
74.

} // namespace sycl

SYCL アプリケーションの相互運用性をサポートする SYCL ランタイムクラス T ごとに、適切なテンプレート関数 make_{sycl_class}の特殊化を定義する必要があります。{sycl_class} は T のクラス名であり、SYCL アプリケーションの相互運用性ネイティブ・バックエンド・オブジェクトを取得し、T のインスタンスを返します。これらのテンプレート関数の可用性と動作は、SYCL バックエンド仕様のドキュ
メントで定義されています。
SYCL コンテキスト・オブジェクトを引数とする make_{sycl_class} 関数のオーバーロードは、与えられる SYCL コンテキストのバックエンドがターゲットのバックエンドと一致しない場合、errc::backend_mismatch エラーコードの例外をスローする必要があります。

4.5.2. 共通参照セマンティクス
次の SYCL ランタイムクラスは、以下のステートメントに従う必要があります： accessor、buffer、context、device、device_image、event、
host_accessor 、 host_sampled_image_accessor 、 host_unsampled_image_accessor 、 kernel 、 kernel_id 、 kernel_bundle 、
local_accessor、platform、queue、sampled_image、sampled_image_accessor、unsampled_image、stream、unsampled_image、
unsampled_image_accessor。ここで T はランタイム・クラス・タイプです。

• T が有効なカーネル引数である場合、T はホスト・アプリケーションおよび SYCL カーネル関数内でコピー構築可能、およびコ
ピー割り当て可能でなければなりません。コピー・コンストラクターまたはコピー代入オペレーターにより別のインスタンスのコピーとして作成された T のインスタンスは、オリジナルのインスタンスのように、またはオリジナルのインスタンスで実行するアクションのように動作する必要があります。そして、オリジナルのインスタンスと同じネイティブ・バックエンド・オブジェクトを表現する必要があります。

• T が有効なカーネル引数である場合、T はホスト・アプリケーションおよび SYCL カーネル関数で破棄可能でなければなりません。
コピー代入オペレーターの結果を含む T のインスタンスが破棄されると、破棄の実行として指定される T に固有の動作は、前述のコピーの定義に従って、このインスタンスが最後に残されたホストコピーである場合にのみ実行されます。

• T が有効なカーネル引数である場合、T はホスト・アプリケーションおよび SYCL カーネル関数内でムーブ可能、およびムーブ割
り当て可能である必要があります。ムーブ・コンストラクターまたはムーブ代入オペレーターにより別のインスタンスのムーブとして作成された T のインスタンスは、オリジナルのインスタンスを置き換えてそのインスタンスを無効化し、該当する場合はオリジ
ナルのインスタンスと同じネイティブ・バックエンド・オブジェクトを表現する必要があります。

• T はホスト・アプリケーションで等価で化ければなりません。T の 2 つのインスタンス間の等式 (a == b) は、一方のインスタンスが他方のインスタンスのコピーである場合 true でなければならず、T の 2 つのインスタンス間の不等式 (a != b) は、どちらのインスタンスもコピーではないなら true でなければなりません。前述の定義に従って、どちらかのインスタンスも他方のコピーではない
場合、いずれかのインスタンスがムーブ操作により無効化された場合を除きます。上記の要件を拡張することで、T の等式は反射
的 (a == a)、対称的 (a == b は b == a、a != b は b != a)、推移的 (a == b && b == c は c == a) を意味します。

第 4 章 SYCL プログラミング・インターフェイス | 49

SYCL 2020 リビジョン 6 - 4.5 共通インターフェイス• T の std::hash の特殊化は、一意な値を返すホスト・アプリケーションにある必要があります。これにより、上記の定義に従って、Tの 2 つのインスタンスが等価である結果のハッシュ値も等しくなり、2 つのハッシュ値が等しくなければ対応するインスタンスも等価ではありません。
一部の SYCL ランタイムクラスには、コピー、ムーブ、割り当て、または破棄のセマンティクスに関連する追加の動作があります。これらが指定される場合、特に明記されない限り上記で指定されるものに追加されます。
上記のランタイムクラスは、コピー、ムーブ、割り当て、または破棄の要件を満たすため特殊メンバー関数の共通インターフェイスを提供し、同等の要件を満たす非表示のフレンド関数を提供する必要があります。
非表示のフレンド関数は、クラス外部または名前空間スコープ宣言を追加することなく、friend 宣言で最初に宣言される関数です。非表示のフレンド関数は、ADL (Argument Dependent Lookup - 引数依存ルックアップ) でのみ表示され、修飾および非修飾ルックアップでは非表示になります。非表示のフレンド関数には、偶発的な暗黙の変換を回避し、コンパイルを高速化する利点があります。
一般的な特殊メンバー関数と隠しフレンド関数を表 7 と表 8 に示します。
1.

namespace sycl {2.
3.

class T {

4.

...

5.
6.

public:7.

T(const T& rhs);

8.
9.

T(T&& rhs);

10.
11.

T& operator=(const T& rhs);

12.
13.

T& operator=(T&& rhs);

14.
15.

~T();

16.
17.

...

18.
19.

friend bool operator==(const T& lhs, const T& rhs) { /* ... */ }

20.
21.

friend bool operator!=(const T& lhs, const T& rhs) { /* ... */ }

22.
23.

...

24.
25.

};
} // namespace sycl

表 7. 参照セマンティクスの一般的な特殊メンバー関数
特殊メンバー関数

説明

T(const T& rhs)

上記の要件に従って、RHS SYCL T のコピーとして T インスタン
スを作成します。

T(T&& rhs)

上記の要件に従って、RHS SYCL T ムーブ として SYCL T インス
タンスを作成します。

50 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.5 共通インターフェイス

特殊メンバー関数

説明

T& operator=(const T& rhs)

上記の要件に従って、SYCL T インスタンスに RHS SYCL T のコ
ピーを割り当てます。

T& operator=(T&& rhs)

上記の要件に従って、SYCL T インスタンスに RHS SYCL T をムーブして割り当てます。

~T()

4.5.2 節に示す要件に従って、SYCL T インスタンスを破棄します。
この SYCL T インスタンスが、4.5.1.3 節で示されるバックエンド
相互運用性 make_* 関数により最初に作成された場合、最後のコピーを破棄する際に、SYCL バックエンド仕様のドキュメントで説明されるネイティブ・バックエンド・オブジェクトに必要な追加のライフタイムに関連する操作を実行できます。詳しくは、関連するバックエンドの仕様を参照してください。

表 8. 参照セマンティクスの一般的な隠匿されたフレンド関数
隠匿されたフレンド関数

説明bool operator==(const T& lhs, const T& rhs)

LHS SYCL T が上記の要件に従って RHS SYCL T と等しい場合
は true を返し、それ以外は false を返します。

bool operator!=(const T& lhs, const T& rhs)

LHS SYCL T が上記の要件に従って RHS SYCL T と等しくない
場合は true を返し、それ以外は false を返します。

4.5.3. 共通値渡しセマンティクス
次の SYCL ランタイムクラスは、以下のステートメントに従う必要があります: id、range、item、nd_item、h_item、group、sub_groupおよび nd_range。
ここで、T はランタイム・クラス・タイプです。

• T は、ホスト・アプリケーション (ホストで T が利用できる場合) および SYCL カーネル関数内でデフォルトでコピー作成可能およびコピー代入可能でなければなりません。

• T は、ホスト・アプリケーション (ホストで T が利用できる場合) および SYCL カーネル関数内でデフォルトで破棄可能でなければなりません。

• T は、ホスト・アプリケーション (ホストで T が利用できる場合) および SYCL カーネル関数内でデフォルトでムーブ作成可能およびムーブ代入可能でなければなりません。

• T は、ホスト・アプリケーション (ホストで T が利用できる場合) および SYCL カーネル関数内で比較可能でなければなりません。
T の 2 つのインスタンス間の等式 (a == b) はすべてのメンバーが等しい場合は true、いずれかのメンバーが等しくない場合は、インスタンスがムーブ操作で無効化されない限り、T の 2 つのインスタンス間の不等式 (a != b) は truie でなければなりません。
上記の要件を拡張することで、T の等式は反射的 (a == a)、対称的 (a == b は b == a、a != b は b != a)、推移的 (a == b && b ==c は c == a) を意味します。
一部の SYCL ランタイムクラスには、コピー、ムーブ、割り当て、または破棄のセマンティクスに関連する追加の動作があります。これらが指定される場合、特に明記されない限り上記で指定されるものに追加されます。

第 4 章 SYCL プログラミング・インターフェイス | 51

SYCL 2020 リビジョン 6 - 4.5 共通インターフェイス
上記のランタイムクラスは、5 の法則と 0 の法則に従って、コピー、ムーブ、破棄、および等価の要件を満たすため、特殊メンバー関数とメンバー関数の共通インターフェイスを提供する必要があります。
一般的な特殊メンバー関数と隠しフレンド関数を表 9 と表 10 に示します。
1.

namespace sycl {2.
3.

class T {

4.

...

5.
6.

public:7.

// 次の 5 つのメンバー関数のいずれかが、パブリック、インライン、

8.

// またはデフォルトでない場合、すべてを明示的に宣言する

9.

// 必要があります (5 の法則を参照 )10.

// それ以外は、明示的に宣言してはなりません11.

// (0 の法則を参照)。

12.
13.

// T(const T& rhs);

14.
15.

// T(T&& rhs);

16.
17.

// T& operator=(const T& rhs);

18.
19.

// T& operator=(T&& rhs);

20.
21.

// ~T();

22.
23.

...

24.
25.

friend bool operator==(const T& lhs, const T& rhs) { /* ... */ }

26.
27.

friend bool operator!=(const T& lhs, const T& rhs) { /* ... */ }

28.
29.

...

30.
31.

};
} // namespace sycl

表 9. 値渡しセマンティクスの一般的な特殊メンバー関数
特殊メンバー関数 (5 の法則と 0 の法則を参照)

説明

T(const T& rhs);

コピー・コンストラクター。

T(T&& rhs);

ムーブ・コンストラクター。

T& operator=(const T& rhs);

コピー代入オペレーター。

T& operator=(T&& rhs);

ムーブ代入オペレーター。

~T();

デストラクター。

52 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.5 共通インターフェイス
表 10.値渡しセマンティクスの共通の隠匿されたフレンド関数
隠匿されたフレンド関数

説明bool operator==(const T& lhs, const T& rhs)

LHS SYCL T が上記の要件に従って RHS SYCL T と等しい場合
は true を返し、それ以外は false を返します。

bool operator!=(const T& lhs, const T& rhs)

LHS SYCL T が上記の要件に従って RHS SYCL T と等しくない場
合は true を返し、それ以外は false を返します。

4.5.4. プロパティー
次の SYCL ランタイムクラスは、各コンストラクターにオプションのパラメーターを与え、0 個以上のプロパティーを含む property_list
を提供します: accessor、buffer、host_accessor、host_sampled_image_accessor、host_unsampled_image_accessor、context、
local_accessor、queue、sampled_image、sampled_image_accessor、stream、unsampled_image、unsampled_image_accessor、
usm_allocator。これらのプロパティーは、特定の機能でクラスのセマンティクスを追加します。これらのクラスは、特定のプロパティーを照会するため has_property と get_property メンバー関数を提供する必要があります。
次のリストは、4.7.2.2 節で説明するバッファー・プロパティーの使い方を示します。
この例では、プロパティーがオブジェクト・タイプに影響しないため、コンテナーの SYCL オブジェクトの利用が妨げられないことを示し
ています。
1.

{

2.

context ｍｙContext；

3.
4.

std::vector<buffer<int, 1>> bufferList {5.

buffer<int, 1>{ptr, rng},

6.

buffer<int, 1>{ptr, rng, property::use_host_ptr{}},7.

buffer<int, 1>{ptr, rng, property::context_bound{myContext}}

8.

};

9.
10.

for(auto& buf : bufferList) {11.

if (buf.has_property<property::context_bound>()) {12.

auto prop = buf.get_property<property::context_bound>();13.

assert(myContext == prop.get_context());

14.

}

15.
16.

}
}

各プロパティーは一意のクラスで表され、プロパティーのインスタンスはそのタイプのインスタンスとなります。一部のプロパティーはデフォルトで作成できますが、ほかのプロパティーには作成時に引数が必要です。プロパティーは複数のクラスに適用できる場合がありま
すが、一部のプロパティーには相互互換性がないことがあります。表 41 と表 48 の SYCL buffer クラス、SYCL unsampled_image クラス、SYCL sampled_image クラスのプロパティーの要件を参照してください。
property_list のインスタンスを介してプロパティーを SYCL ランタイムクラスに渡すことができます。これらのプロパティーは、SYCL
ランタイムクラスのインスタンスに関連付けられ、オブジェクトのコピーには同じプロパティーが含まれています。
SYCL 実装や SYCL バックエンドが 4.3 節で説明する要件に従って定義される場合、ここで定義されるプロパティー以外の追加のプロ
パティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 53

SYCL 2020 リビジョン 6 - 4.5 共通インターフェイス

4.5.4.1. プロパティー・インターフェイス
上記のランタイムクラスは、プロパティー・インターフェイスの要件を満たすため、メンバー関数の共通インターフェイスを提供する必要があります。
以下に、共通プロパティー・インターフェイス、SYCL property_list クラス、および SYCL プロパティー・クラスの概要を示します。共通プロパティー・インターフェイスのメンバー関数を表 12 に、SYCL property_list クラスのコンストラクターを表 13 に示します。
1.

namespace sycl {2.
3.

template <typename Property>

4.

struct is_property;

5.
6.

template <typename Property >7.

inline constexpr bool is_property_v = is_property< Property>::value;8.
9.

template <typename Property , typename SyclObjectT>

10.

struct is_property_of;

11.
12.

template <typename Property , typename SyclObjectT>

13.

inline constexpr bool is_property_of_v = is_property_of< Property , SyclObjectT>::value;

14.
15.

class T {

16.

...

17.
18.

template <typename Property >19.

bool has_property() const noexcept;

20.
21.

template <typename Property >22.

Property get_property() const;

23.
24.

...

25.

};

26.
27.

class property_list {28.

public:29.

template <typename... Properties>

30.

property_list(Properties... props);

31.
32.

};
} // namespace sycl

表 11. プロパティーの特性
特性 (Traits)説明

template <typename Property>

std::true_type から継承する is_property の明示的な特殊化は、

struct is_property

プロパティーごとに用意する必要があります。ここで、Property
はプロパティーを定義するクラスです。これには、この仕様で定義される標準プロパティーと、実装定義の追加の非標準プロパティーの両方が含まれています。is_property のほかの特殊化
は、std::false_type から継承します。

54 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

特性 (Traits)説明

template <typename Property>

is_property<Property> の値を含む変数。

inline constexpr bool is_property_v;
template <typename Property, SyclObject>

std::true_type から継承する is_property_of の明示的な特殊化

struct is_property_of

は、プロパティーごとに用意する必要があります。ここで、Property はプロパティーを定義するクラスであり、SyclObject
は SYCL クラスです。これには、この仕様で定義される標準プロ
パティーと、実装定義の追加の非標準プロパティーの両方が含まれています。is_property_of のほかの特殊化は、std::false_type
から継承します。

template <typename Property, syclObjectT>

is_property_of<Property, SyclObject> の値を含む変数。

inline constexpr bool is_property_of_v;

表 12. SYCL property インターフェイスの共通メンバー関数
メンバー関数説明

template <typename Property>

T が Property で指定されたプロパティーで作成された場合 truebool has_property() const noexceptを返します。それ以外は false を返します。

template <typename Property>

T が作成された Property タイプのプロパティーのコピーを返し

propertyT get_property() const

ます。T が Property プロパティーで作成されていない場合、
errc::invalid エラーコードの例外をスローする必要があります。

表 13. SYCL property_list クラスのコンストラクター
コンストラクター

説明

template <typename... PropertyN>

is_property<property>::value が true であると評価された場合

property_list(PropertyN... props)にのみ使用できます。property は PropertyN の各プロパティーです。
ゼロ個以上のプロパティーで SYCL property_list を作成します。

4.6. SYCL ランタイムクラス
4.6.1. デバイスの選択システムには、複数の SYCL 互換デバイスを接続可能であり、特定のデバイスまたはデバイスセットを選択して、device (4.6.4 節を参照) または queue (4.6.5 節を参照) など特定のオブジェクトを作成したり、デバイスのサブセットで特定の操作を実行すると便利です。
デバイスの選択は、device に固有のインスタンスをすでに保有しているか (4.6.4 節を参照)、またはシステム上のデバイスに整数値のランクを割り当てるランキング関数である、デバイスセレクターを提供することで実現されます。

第 4 章 SYCL プログラミング・インターフェイス | 55

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

4.6.1.1. デバイスセレクター
デバイスセレクターのインターフェイスは、C++ の名前付き呼び出し可能要件を満たす任意のオブジェクトであり、const device& タイプのパラメーターを受け取り、int タイプに暗黙的に変換可能な値を返します。
SYCL ランタイムがデバイスセレクターを使用して SYCL device を選択する場合、システムは常にシステム内のすべての SYCL バック
エンドから利用可能なルートデバイスを照会し、それぞれのデバイスのデバイスセレクターを呼び出して、最も高いスコアのデバイスを選択します。最も高いスコアが負の場合、デバイスは選択されません。
単一のデバイスのみを選択する必要があるため、複数のデバイスが同一のスコアを返す場合デバイスの 1 つが返されますが、例えば、
SYCL ランタイムの制御外など、一方が未定義で列挙順序に依存する可能性があります。
一部の事前定義されたデバイスセレクターは、表 14 で示すように、次のような定義のヘッダーファイルがシステムによって提供されます。
表 14. すべての SYCL 実装に含まれる標準デバイスセレクター
SYCL デバイスセレクター

説明default_selector_v

実装で定義されたヒューリスティックに基づいて、サポートされる
SYCL バックエンドから SYCL device を選択します。すべての実装は少なくとも 1 つのデバイスをサポートする必要があり、セレク
ターは常にデバイスを返す必要があります。
実装では、システムに利用可能な物理デバイスが存在しない場合、フォールバックとしてエミュレートされたデバイス (aspect::emulated を使用) を返すことを選択できます。

gpu_selector_v

SYCL バ ッ ク エ ン ド で サ ポ ー ト さ れ る デ バ イ ス タ イ プ が
info::device_type::gpu である SYCL device を選択します。この要件に一致するデバイスが見つからない場合、SYCL クラス・コン
ストラクターは、errc::runtime エラーコードで例外をスローする必要があります。

accelerator_selector_v

SYCL バ ッ ク エ ン ド で サ ポ ー ト さ れ る デ バ イ ス タ イ プ が
info::device_type::accelerator である SYCL device を選択します。この要件に一致するデバイスが見つからない場合、SYCL クラ
ス・コンストラクターは、errc::runtime エラーコードで例外をスローする必要があります。

cpu_selector_v

SYCL バ ッ ク エ ン ド で サ ポ ー ト さ れ る デ バ イ ス タ イ プ が
info::device_type::cpu である SYCL device を選択します。この要件に一致するデバイスが見つからない場合、SYCL クラス・コン
ストラクターは、errc::runtime エラーコードで例外をスローする必要があります。

56 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

SYCL デバイスセレクター

説明__unspecified_callable__ aspect_selector(

aspect_selector 関数にはいくつかのオーバーロードがあり、それぞconst std::vector<aspect>& aspectList,

れが要求されたアスペクトを含む SYCL バックエンドから SYCL

const std::vector<aspect>& denyList = {});

device を選択するセレクター・オブジェクトを返します。例えば、特定 の デ バ イ ス dev お よ び aspectList dev.has(devAspect) のtemplate <typename... AspectList>

devAspect が true である場合。アスペクトが渡されない場合、生成__unspecified_callable__ aspect_selector

されたセレクターは default_selector として動作します。

(AspectList... aspectList);
アスペクトは、関数のオーバーロードに応じて、ベクトル、関数のtemplate <aspect... AspectList>

引数、またはテンプレート・パラメーターとして渡すことができま__unspecified_callable__ aspect_selector();す。aspectList リストをベクトルとして受け取る関数のオーバー
ロードは、ユーザーが否定するすべてのアスペクトを指定する別のベクトル引数 denyList を受け取ります。つまり、特定のデバイ
ス dev および denyList dev.has(devAspect) の devAspect はfalse になります。
この要件に一致するデバイスが見つからない場合、生成されたセ
レ ク タ ー を 使 用 す る SYCL ク ラ ス ・ コ ン ス ト ラ ク タ ー は 、
errc::runtime エラーコードで例外をスローする必要があります。
この関数には複数のオーバーロードがあります。完全な定義につい て は 、 [header:device-selector] を 、 使 用 例 に つ い て は[example:aspect-selector] を参照してください。

1.

namespace sycl {2.
3.

// 事前定義されたデバイスセレクター

4.

__unspecified__ default_selector_v;

5.

__unspecified__ cpu_selector_v;

6.

__unspecified__ gpu_selector_v;

7.

__unspecified__ accelerator_selector_v;

8.
9.

// 古い SYCL 1.2.1 デバイスセレクターとの互換性を維持するために事前定義されたタイプ

10.

using default_selector = __unspecified__;11.

using cpu_selector = __unspecified__;12.

using gpu_selector = __unspecified__;13.

using accelerator_selector = __unspecified__;

14.
15.

// 必要なアスペクトをベースにデバイスを選択するセレクターを返します16.

__unspecified_callable__ aspect_selector(

17.

const std::vector<aspect>& aspectList,

18.

const std::vector<aspect>& denyList = {});

19.

template <class... AspectList>

20.

__unspecified_callable__ aspect_selector(AspectList... aspectList);21.

template <aspect... AspectList>

22.

__unspecified_callable__ aspect_selector();

23.
24.

} // namespace sycl

第 4 章 SYCL プログラミング・インターフェイス | 57

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
デフォルトおよびユーザーが提供するデバイスセレクターの例を以下に示します。
1.

sycl::device my_gpu { sycl::gpu_selector_v };2.
3.

sycl::queue my_accelerator { sycl::accelerator_selector_v };4.
5.

int prefer_my_vendor(const sycl::device& d) {6.

// ベンダー名が 「MyVendor」 の場合は 1、それ以外は 0 を返します7.

// 0 は、別のデバイスが第 2 の選択肢となることを妨げません

8.

return d.get_info<info::device::vendor>() == "MyVendor";

9.

}

10.
11.

// 利用できない場合、優先デバイスまたは別のデバイスを取得します

12.

sycl::device preferred_device { prefer_my_vendor };

13.
14.

// システムにデバイスがない場合、スローされます15.

sycl::queue half_precision_controller {16.

// ラムダをデバイスのランキング関数として使用できます17.

// デバイスがない場合、負の値を返します。

18.

[] (auto& d) { return d.has(sycl::aspect::fp16) ? 1 : -1; }

19.

};

20.
21.

// SYCL 1.2.1 コードの移植を容易にするため、同等の事前定義された

22.

// デバイスセレクターを構築するタイプがあります23.

sycl::queue my_old_style_gpu { sycl::gpu_selector {} };aspect_selector の使い方の例:
1.

using namespace sycl; // (オプション) SYCL 名の前に “sycl::” は必要ありません

2.
3.

// default_selector と同等の制限のない選択

4.

auto dev0 = device{aspect_selector()};5.
6.

// アスペクトをベクトルで渡します7.

// 半精度をサポートする CPU のみを受け入れます8.

auto dev1 = device{aspect_selector(std::vector{aspect::cpu, aspect::fp16})};9.
10.

// アスペクトをベクトルなしで渡します11.

// 半精度をサポートする GPU のみを受け入れます12.

auto dev2 = device{aspect_selector(aspect::gpu, aspect::fp16)};

13.
14.

// アスペクトをコンパイル時のパラメーターとして渡します15.

// ホスト上でデバッグ可能で半精度をサポートするデバイスのみを受け入れます16.

auto dev3 = device{aspect_selector<aspect::host_debuggable, aspect::fp16>()};

17.
18.

// allowlist と denylist でアスペクトを渡します19.

// 浮動小数点の半精度と倍精度をサポートするデバイスのみを受け入れますが、

20.

// エミュレートされたデバイスと "custom" タイプのデバイスは除きます

21.

auto dev4 = device{aspect_selector(

22.

std::vector{aspect::fp16, aspect::fp64},

23.

std::vector{aspect::emulated, aspect::custom}

24.

)};

58 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

SYCL 1.2.1 では、事前定義されたデバイスセレクターは、使用するにはインスタンス化する必要があるタイプでした。このバージョンではインスタンスになりました。古いタイプのインスタンス化を使用するコードの移植を簡素化するため、sycl::default_selector などの下位互換の API が引き続き提供されます。新しい事前定義デバイスセレク
ターには、競合を回避するため名称に "_v" が追加されており、C++ 標準ライブラリーの特性で使用される命名スタ
イルと類似しています。しかし、sycl::gpu_selector_v が sycl::gpu_selector のインスタンスであるというような実装の要件はありません。
実装の注意: SYCL API では、デフォルト・パラメーターによるコンストラクターのあいまいさを解決するため、
SFINAE または C++20 の概念に従う場合があります。

4.6.2. プラットフォーム・クラス
SYCL platform クラスは、カーネル関数を実行する単一の SYCL プラットフォームをカプセル化します。SYCL platform は、単一の
SYCL バックエンドに関連付ける必要があります。
SYCL platform はまた、同一 SYCL バックエンドに関連する 1 つ以上の SYCL devices に関連付けることもできます。
platform クラスのすべてのメンバー関数は同期的であり、エラーは同期 SYCL 例外をスローすることで処理されます。
SYCL アプリケーションの実行環境には、アプリケーション実行時に変化しない固定数のプラットフォームがあります。アプリケーショ
ンは、platform::get_platforms() を使用してすべてのプラットフォーム・リストを取得でき、プラットフォーム・オブジェクトの順序は関数を呼び出すたびに常に同じになります。platform クラスはコンストラクターも提供しますが、新しい platform インスタンスを構築すると、platform::get_platforms() が返すオブジェクトのコピーである新しいオブジェクトが作成されるだけで済みます。
SYCL platform クラスは、共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.6.2.1. プラットフォーム・インターフェイスSYCL platform クラスの概要を以下に示します。SYCL platform クラスのコンストラクター、メンバー関数、および静的メンバー関数
については、表 15、表 16 および表 17 をご覧ください。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7と表 8 ご覧ください。
1.

namespace sycl {2.

class platform {3.
4.

public:platform();

5.
6.

template <typename DeviceSelector>

7.

explicit platform(const DeviceSelector& deviceSelector);

8.
9.

/* -- 共通インターフェイスのメンバー -- */

10.
11.

backend get_backend() const noexcept;

12.
13.
14.

std::vector<device> get_devices(
info::device_type = info::device_type::all) const;

15.
16.

template <typename Param> typename Param::return_type get_info() const;

17.

第 4 章 SYCL プログラミング・インターフェイス | 59

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
18.

template <typename Param>

19.

typename Param::return_type get_backend_info() const;

20.
21.

bool has(aspect asp) const;

22.
23.

bool has_extension(const std::string& extension) const; // 非推奨

24.
25.

static std::vector<platform> get_platforms();

26.
27.

};
} // namespace sycl

表 15. SYCL platform クラスのコンストラクター
コンストラクター説明

platform()default_selector_v が返すデバイスを含む platform のコピーである SYCL platform のインスタンスを構築します。

template <typename DeviceSelector>
explicit platform(const DeviceSelector&)

デバイスセレクターのパラメーターが返すデバイスを含む
platform のコピーである SYCL platform のインスタンスを構築します。

表 16. SYCL platform クラスのメンバー関数
メンバー関数説明

backend get_backend() const noexcept

この platform に関連付けられている SYCL バックエンドを識別する backend を返します。

template <typename Param> typename

SYCL platform のテンプレート・パラメーター Param で要求さParam::return_type

れる情報を照会します。タイプエイリアス Param::return_type

get_info() const

は、Param パラメーターに関連付けられたタイプを返すため、表25 の info パラメーターに従って定義する必要があります。

template <typename Param> typename

テンプレート・パラメーター Param が要求する SYCL バックエン

Param::return_type

ド固有の情報について SYCL platform を照会します。タイプエイ

get_backend_info() const

リアス Param::return_type は、SYCL バックエンド仕様に従って定義する必要があります。Param に対応する SYCL バックエンド
が、platform に関連付けられる SYCL バックエンドと異なる場
合、errc::backend_mismatch エラーコードで例外をスローする必要があります。

bool has(aspect asp) const

この SYCL platform に関連付けられているすべての SYCL
device が指定する aspect を保持する場合 true を返します。

60 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

bool has_extension(const std::string& extension) const

非推奨。代わりに has() を使用します。
この SYCL platform が extension パラメーターで照会される機能をサポートする場合 true を返します。SYCL platform は、関連するすべての SYCL device が extension をサポートする場合にのみ拡張機能をサポートします。

std::vector<device> get_devices(

deviceType によってカプセル化されたデバイスタイプを持つ

info::device_type deviceType =SYCL platform に関連付けられたすべての SYCL device を含む

info::device_type::all) const

std::vector を返します。

表 17. SYCL platform クラスの静的メンバー関数
スタティック・メンバー関数

説明

static std::vector<platform> get_platforms()

システムで利用可能なすべての SYCL バックエンドから SYCL
platforms を含む std::vector を返します。

4.6.2.2. プラットフォーム情報記述子
プラットフォームでは、platform クラスの get_info メンバー関数を使用して、info::platform の info パラメーターで情報を照会できます。すべてのプラットフォームは、info パラメーターに対し有効な値を持つ必要があります。
それぞれの info パラメーターに設定可能な値と制限は、プラットフォームに関連する SYCL バックエンドの仕様で定義されています。
info::platform のすべての info パラメーターは表 18 に示し、info::platform の概要はA.1 節で説明します。
表 18. プラットフォーム情報記述子
プラットフォーム記述子

戻り値

説明

info::platform::version

std::string

バックエンドにあるプラットフォームのバージョンを返します。

info::platform::name

std::string

プラットフォーム名を返します。

info::platform::vendor

std::string

プラットフォームを提供するベンダー名を返します。

info::platform::extensions

std::vector

非推奨。代わりに info::device::aspects とともに device::get_info()<std::string>を使用します。
プラットフォームでサポートされる拡張機能を返します。

4.6.3. コンテキスト・クラス
コンテキスト・クラスは SYCL コンテキストを表します。コンテキストは、プラットフォームに関連付けられたデバイスグループと対話するため、SYCL バックエンド API が必要とするランタイムのデータ構造と状態を表します。

第 4 章 SYCL プログラミング・インターフェイス | 61

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
SYCL context クラスは、共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.6.3.1. コンテキスト・インターフェイスSYCL context クラスのコンストラクターとメンバー関数を表 19 と表 20 に示します。追加の共通特殊メンバー関数と共通メンバー
関数については、4.5.2 節の表 7 と表 8 を参照してください。
context クラスのすべてのメンバー関数は同期的であり、エラーは同期 SYCL 例外をスローすることで処理されます。
SYCL context クラスのすべてのコンストラクターは、コンストラクターのパラメーターで示される特定の SYCL バックエンドに関連付けられるインスタンスを構築するか、デフォルトのコンストラクターでは default_selector_v で生成される SYCL device を構築します。
SYCL context は、オプションで async_handler パラメーターを使用して構築できます。この場合、4.13 節で説明されるように、
async_handler は非同期 SYCL 例外をレポートする際に使用されます。SYCL context に関連する情報は get_info() メンバー関数で照会できます。
1.

namespace sycl {2.

class context {3.
4.

public:explicit context(const property_list& propList = {});

5.
6.
7.

explicit context(async_handler asyncHandler,
const property_list& propList = {});

8.
9.

explicit context(const device& dev, const property_list& propList = {});

10.
11.

explicit context(const device& dev, async_handler asyncHandler,

12.

const property_list& propList = {});

13.
14.
15.

explicit context(const std::vector<device>& deviceList,
const property_list& propList = {});

16.
17.

explicit context(const std::vector<device>& deviceList,

18.

async_handler asyncHandler,

19.

const property_list& propList = {});

20.
21.

/* -- プロパティー・インターフェイスのメンバー -- */

22.
23.

/* -- 共通インターフェイスのメンバー -- */

24.
25.

backend get_backend() const noexcept;

26.
27.

platform get_platform() const;

28.
29.

std::vector<device> get_devices() const;

30.
31.

template <typename Param> typename Param::return_type get_info() const;

32.
33.

template <typename Param>

34.

typename Param::return_type get_backend_info() const;

62 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
35.
36.

};
} // namespace sycl

表 19. SYCL context クラスのコンストラクター
コンストラクター

説明

explicit context(async_handler asyncHandler = {})default_selector_v のインスタンスを使用して SYCL context イ
ンスタンスを構築し、関連する SYCL platform と device を選択します。構築されるコンテキストに関連するデバイスは実装定義
ですが、デバイスセレクターで選択されるデバイスが含まれる場
合があります。構築される SYCL context は asyncHandler パラ
メーターを使用して例外を処理します。

explicit context(const device& dev,

SYCL device に関連付けら れた dev パラメーターと、 SYCL

async_handler asyncHandler = {})platform に関連付けられた dev パラメーターに関連する SYCL
platform を使用して SYCL context インスタンスを構築します。
構築される SYCL context は asyncHandler パラメーターを使用して例外を処理します。

explicit context(const std::vector<device>& deviceList,
async_handler asyncHandler = {})SYCL device に関連付けられた deviceList パラメーターと、
SYCL platform に関連付けられた SYCL device の deviceList
パ ラ メ ー ター に 関 連 す る SYCL platform を 使 用 し て SYCL
context インスタンスを構築します。これには、deviceList パラ
メーター内のすべての SYCL device が同じ SYCL platform に関連付けられている必要があります。構築される SYCL context はasyncHandler パラメーターを使用して例外を処理します。

表 20. context クラスのメンバー関数
メンバー関数説明

backend get_backend() const noexcept

この context に関連付けられている SYCL バックエンドを識別する backend を返します。

template <typename Param>

テンプレート・パラメーター Param で要求される情報の SYCL

typename Param::return_type

context を照会します。タイプエイリアス Param::return_type

get_info() const

は、Param パラメーターに関連付けられたタイプを返すため、表21 の info パラメーターに従って定義する必要があります。

template <typename Param>

テンプレート・パラメーター Param が要求する SYCL バックエン

typename Param::return_type

ド固有の情報について SYCL context を照会します。タイプエイリ

get_backend_info() const

アス Param::return_type は、SYCL バックエンド仕様に従って定義する必要があります。Param に対応する SYCL バックエンド
が、context に関連付けられる SYCL バックエンドと異なる場合、
errc::backend_mismatch エラーコードで例外をスローする必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 63

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

platform get_platform() const

SYCL context に関連付けられている SYCL platform を返します。戻り値は、get_info<info::context::platform>() が返す値と同じである必要があります。

std::vector<device>

SYCL context に関連付けられているすべての SYCL devices を含む

get_devices() const

std::vector を返します。戻り値は、get_info<info::context::devices>()が返す値と同じである必要があります。

4.6.3.2. コンテキスト情報記述子
コンテキストでは、context クラスの get_info メンバー関数を使用して、info::context の info パラメーターで情報を照会できます。すべてのコンテキストは、info パラメーターに対し有効な値を持つ必要があります。それぞれの info パラメーターに設定可能な値と制限
は、コンテキストに関連する SYCL バックエンドの仕様で定義されています。info::context のすべての info パラメーターは表
21Table_21 に示し、info::context の概要は A.2 節で説明します。
表 21. コンテキスト情報記述子
コンテキスト記述子

戻り値

説明

info::context::platform

platform

コンテキストに関連付けられたプラットフォームを返します。

info::context::devices

std::vector

コンテキストに関連付けられたデバイスを返します。

<device>
info::context::atomic_memory_order_c std::vector

コンテキスト内のすべてのデバイスのアトミック操作でサポート

apabilities

されるメモリー順序のセットを返します。これは、relaxed (緩和さ<memory_order>れる) であることが保証されます。
コンテキストのメモリー順序は、アトミック操作を決定します。コンテキスト内の複数のデバイスから同時にアクセス可能なメモリーに適用されます。
info::context::atomic_fence_order_cap std::vector

コンテキスト内のすべてのデバイスの atomic_fence でサポート

abilities

さ れ る メ モ リ ー 順 序 の セ ッ ト を 返 し ま す 。 こ れ は 、 relaxed 、<memory_order>

acquire、release、acq_rel であることが保証されます。
コンテキストのメモリー順序は、アトミック操作を決定します。コンテキスト内の複数のデバイスから同時にアクセス可能なメモリーに適用されます。
info::context::atomic_memory_scope_

std::vector

capabilities<memory_scope> さ れ る メ モ リ ー ス コ ー プ の セ ッ ト を 返 し ま す 。 こ れ は 、

コンテキスト内のすべてのデバイスのアトミック操作でサポート
work_group を含むことが保証されます。

64 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

コンテキスト記述子

戻り値

info::context::atomic_fence_scope_cap std::vector
abilities

説明
コンテキスト内のすべてのデバイスの atomic_fence でサポート<memory_scope> されるメモリー順序のセットを返します。これは、work_group を含むことが保証されます。

4.6.3.3. コンテキスト・プロパティー
property_list コンストラクター・パラメーターは拡張性のために使用されます。

4.6.4. デバイスクラス
SYCL device クラスは、カーネルを実行する単一の SYCL デバイスをカプセル化します。
device クラスのすべてのメンバー関数は同期的であり、エラーは同期 SYCL 例外をスローすることで処理されます。
SYCL アプリケーションの実行環境には、アプリケーション実行時に変化しない固定数のルートデバイスがあります。アプリケーション
は、device::get_devices() を使用してすべてのデバイスリストを取得でき、デバイス・オブジェクトの順序は、関数パラメーターが同じであれば、関数を呼び出すたびに常に同じになります。device クラスはコンストラクターも提供しますが、新しい device インスタンスを構築すると、device::get_devices() が返すオブジェクトのコピーである新しいオブジェクトが作成されるだけで済みます。
create_sub_devices() メンバー関数テンプレートを呼び出して、SYCL device を複数の SYCL デバイスに区分けできます。その結果
SYCL devices はサブデバイスと見なされ、それらをさらに区分することもできます。この機能のサポートは SYCL バックエンドとデバ
イス固有であり、get_info() で照会できます。
SYCL device クラスは共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.6.4.1. デバイス・インターフェイスSYCL device クラスの概要を以下に示します。SYCL device クラスのコンストラクター、メンバー関数、および静的メンバー関数については、表 22、表 23 および表 24 をご覧ください。追加の共通特殊メンバー関数と共通メンバー関数については、表 7 と表 8 の 4.5.2
節を参照してください。
1.

namespace sycl {2.
3.

class device {4.

public:5.

device();6.
7.

template <typename DeviceSelector>

8.

explicit device(const DeviceSelector& deviceSelector);

9.
10.

/* -- 共通インターフェイスのメンバー -- */

11.
12.

backend get_backend() const noexcept;

13.
14.

bool is_cpu() const;

15.
16.

bool is_gpu() const;

第 4 章 SYCL プログラミング・インターフェイス | 65

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
17.
18.

bool is_accelerator() const;

19.
20.

platform get_platform() const;

21.
22.

template <typename Param> typename Param::return_type get_info() const;

23.
24.

template <typename Param>

25.

typename Param::return_type get_backend_info() const;

26.
27.

bool has(aspect asp) const;

28.
29.

bool has_extension(const std::string& extension) const; // 非推奨

30.
31.

// Prop == info::partition_property::partition_equally のときにのみ利用できます

32.

template <info::partition_property Prop>33.

std::vector<device> create_sub_devices(size_t count) const;

34.
35.

// Prop == info::partition_property::partition_by_counts のときにのみ利用できます

36.

template <info::partition_property Prop>37.

std::vector<device> create_sub_devices(const std::vector<size_t>& counts) const;

38.
39.

// Prop == info::partition_property::partition_by_affinity_domain のときにのみ利用できます40.

template <info::partition_property Prop>41.

std::vector<device> create_sub_devices(info::partition_affinity_domain affinityDomain) const;

42.
43.

static std::vector<device> get_devices(

44.
45.
46.

info::device_type deviceType = info::device_type::all);};} // namespace sycl

表 22. SYCL device クラスのコンストラクター
コンストラクター説明

device()default_selector_v から返されるデバイスのコピーである SYCL
device インスタンスを作成します。

template <typename DeviceSelector>
explicit device(const DeviceSelector&)

device selector パラメーターから返されるデバイスのコピーである SYCL device インスタンスを作成します。

表 23. SYCL device クラスのメンバー関数
メンバー関数説明

backend get_backend() const noexcept

この device に関連付けられている SYCL バックエンドを識別する backend を返します。

platform get_platform() const

関連する SYCL platform を返します。get_info<info::device::
platform>() が返す値と同じでなければなりません。

66 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

bool is_cpu() const

has(aspect::cpu) と同じ値を返します。表 26 を参照してくださいbool is_gpu() const

has(aspect::gpu) と同じ値を返します。表 26 を参照してください。

bool is_accelerator() const

has(aspect::accelerator) と同じ値を返します。表 26 を参照してく
ださい。

template <typename Param>

テンプレート・パラメーター Param で要求される情報の SYCL

typename Param::return_type

device を照会します。タイプエイリアス Param::return_type は、

get_info() const

Param パラメーターに関連付けられたタイプを返すため、表 25の info パラメーターに従って定義する必要があります。

template <typename Param >テンプレート・パラメーター Param で要求される SYCL バックエ

typename Param::return_type

ンド固有の情報について SYCL device を照会します。 タイプエイ

get_backend_info() const

リアス Param::return_type は、SYCL バックエンド仕様に従って定義する必要があります。Param に対応する SYCL バックエンド
が、device に関連付けられる SYCL バックエンドと異なる場合、
errc::backend_mismatch エラーコードで例外をスローする必要があります。

bool has(aspect asp) const

SYCL device が指定された aspect を持つ場合 true を返します。
SYCL アプリケーションは、メンバー関数を使用してデバイスがサポートするオプション機能 (利用できれば) を特定できます。

bool has_extension(
const std::string& extension) const

非推奨。代わりに has() を使用します。
この SYCL device が extension パラメーターで照会される機能をサポートする場合 true を返します。

template <info::partition_property Prop>

Prop が info::partition_property::partition_equally の場合にstd::vector<device> create_sub_devices(のみ利用できます。count パラメーターに基づいて、SYCL device

size_t count) const

からパーティション化されたサブデバイスの std::vector を返します。返されるベクトルにはそれぞれのサブデバイスに count 計算
ユニットが含まれるよう、作成できる限り多くのサブデバイスが
含 ま れ ま す 。 デ バ イ ス の 計 算 ユ ニ ッ ト の 総 数(info::device::max_compute_units で返される) が count で均等に分割できない場合、余りの計算ユニットはいずれのサブデバ
イスにも含まれません。
SYCL device が info::partition_property::partition_equally をサポートしていない場合、errc::feature_not_supported エラー
コードで例外をスローする必要があります。count がデバイス内の計算ユニットの総数を超える場合、errc::invalid エラーコード
で例外をスローする必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 67

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

template <info::partition_property Prop>

Prop が info::partition_property::partition_by_counts の場合

std::vector<device> create_sub_devices(にのみ利用できます。counts パラメーターに基づいて、SYCL

const std::vector<size_t>& counts) const

device からパーティション化されたサブデバイスの std::vectorを返します。counts ベクトルでゼロ以外の値 M ごとに、M 個の計算ユニットを持つサブデバイスが作成されます。
SYCL device が info::partition_property::partition_by_counts
を サ ポ ー ト し て い な い 場 合 、 errc::feature_not_supported
エラーコードの例外をスローする必要があります。ゼロ以外の
counts 値 が デ バ イ ス の サ ブ デ バ イ ス の 最 大 数(info::device::partition_max_sub_devices で返される) を超える
場合、またはcounts ベ ク ト ル の す べ て の 合 計 がデバイスの計算ユニットの合計数を上回る場合(info::device::max_compute_units で 返 さ れ る ) 、 errc::invalid
エラーコードで例外をスローする必要があります。

68 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

template <info::partition_property Prop>

Prop が info::partition_property::partition_by_affinity_domain

std::vector<device> create_sub_devices(の場合にのみ利用できます。domain パラメーターに基づく、アフィ

info::partition_affinity_domain domain) const

ニティー・ドメインによる SYCL device から区分されたサブデバイ
スの std::vector を返します。これは、次のいずれかの値でなければなりません。

• info::partition_affinity_domain::numa: デ バ イ ス をNUMA ノードを共有する計算ユニットで構成されるサブデバイスに分割します。

• info::partition_affinity_domain::L4_cache: デバイスをレベル 4 データキャッシュを共有する計算ユニットで構成されるサブデバイスに分割します。

• info::partition_affinity_domain::L3_cache: デバイスをレベル 3 データキャッシュを共有する計算ユニットで構成されるサブデバイスに分割します。

• info::partition_affinity_domain::L2_cache: デバイスをレベル 2 データキャッシュを共有する計算ユニットで構成されるサブデバイスに分割します。

• info::partition_affinity_domain::L1_cache: デバイスをレベル 1 データキャッシュを共有する計算ユニットで構成されるサブデバイスに分割します。

• info::partition_affinity_domain::next_partitionable: 次のパーティション化可能なアフィニティー・ドメインに沿ってデバイスを分割します。実装では、デバイスもしくはサブデバイ
スを numa、L4_cache、L3_cache、L2_cache、L1_cache の順でさらに細分化可能な最初のレベルを検出して、このレベルでメモリー・サブシステムを共有する計算ユニットで構成されるサブデバイスに分割する必要があります。ユーザーは、info::device::partition_type_affinity_domain を使用して振る舞いを監視できます。
SYCL device が info::partition_property::partition_by_affinity_
domain を サ ポ ー ト し な い 場 合 、 ま た は SYCL device が
info::partition_affinity_domain を サ ポ ー ト し な い 場 合 は 、
errc::feature_not_supported エラーコードで例外をスローする必要があります。

表 24. SYCL device クラスのスタティック・メンバー関数
スタティック・メンバー関数

説明

static std::vector<device> get_devices(

deviceType でカプセル化されたデバイスタイプを持つシステム

info::device_type deviceType = info::device_type::all)で利用可能な SYCL バックエンドのすべての SYCL device を含
む std::vector を返します。

第 4 章 SYCL プログラミング・インターフェイス | 69

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

4.6.4.2. デバイス情報記述子
デバイスでは、device クラスの get_info メンバー関数を使用して、info::device の info パラメーターで情報を照会できます。それぞれの info パラメーターに設定可能な値と制限は、デバイスに関連する SYCL バックエンドの仕様で定義されています。info::device のす
べての info パラメーターは表 25 に示し、info::device の概要は A.3 節で説明します。
表 25. デバイス情報記述子
デバイス記述子

戻り値

説明

info::device::device_type

info::device_typdevice に 関 連 す る デ バ イ ス タ イ プ を 返 し ま す 。 info::device_etype::all を返さないこともあります。

info::device::vendor_id

uint32_t

一意なベンダーデバイス識別子を返します。

info::device::max_compute_units

uint32_t

デバイスで利用可能な並列計算ユニットの数を返します。最小値
は 1 です。

info::device::max_work_item_Dimension

uint32_ts

データ並列実行モデルで使用されるグローバルおよびローカル
work-item ID を指定する最大次元数を返します。SYCL device
がデバイスタイプ info::device_type::custom でない場合、最小値は 3 です。

info::device::max_work_item_sizes<1>

id<1>nd_range の work-group で許容される work-item の最大数を返します。device がデバイスタイプ info::device_type::custom
ではない場合の最小値です。

info::device::max_work_item_sizes<2>id<2>nd_range の work-group の両方の次元で許容される work-itemの 最 大 数 を 返 し ま す 。 device が デ バ イ ス タ イ プ
info::device_type::custom ではない場合の最小値は (1, 1) です。

info::device::max_work_item_sizes<3>id<3>nd_range の work-group の そ れ ぞ れ の 次 元 で 許 容 され る
work-item の 最 大 数 を 返 し ま す 。 device が デ バ イ ス タイ プ
info::device_type::custom ではない場合の最小値は (1, 1, 1)です。

info::device::max_work_group_size

size_t

単一計算ユニットでカーネルを実行する work-group で許容される work-item の最大数を返します。最小値は 1 です。

info::device::max_num_sub_groups

uint32_t

デバイスで実行されたカーネルの work-group 内のサブグルー
プの最大数を返します。最小値は 1 です。

info::device::sub_group_independent_fo bool

デバイスが同一 work-group 内のほかのサブグループで独立しrward_progress

た順方向をサポートする場合 true を返します。

info::device::sub_group_sizes

std::vector

デバイスでサポートされるサブグループのサイズのセットを含む<size_t>size_t の std::vector を返します。

70 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::preferred_vector_width_cha uint32_t

ベクトルに格納できるビルトインのスカラータイプの優先ネイr

ティブベクトル幅のサイズを返します。ベクトル幅は、ベクトルに

info::device::preferred_vector_width_sho

格 納で き るス カラ ー 要素 数と して 定義 でき ます。デ バイス にrtaspect::fp64 が な い 場 合 、 info::device::preferred_vector_

info::device::preferred_vector_width_int

width_double は 0 を 返 し 、 aspect::fp16 が な い 場 合 は

info::device::preferred_vector_width_lon

info::device::preferred_vector_width_half は 0 を返します。

g
info::device::preferred_vector_width_flo
atinfo::device::preferred_vector_width_double
info::device::preferred_vector_width_hal
finfo::device::native_vector_width_char

uint32_t

ネイティブ ISA のベクイトル幅を返します。ベクトル幅は、ベクトル

info::device::native_vector_width_shortに格納できるスカラー要素数として定義できます。デバイスに

info::device::native_vector_width_int

aspect::fp64 が な い 場 合 、 info::device::preferred_vector_

info::device::native_vector_width_long

width_double は 0 を 返 し 、 aspect::fp16 が な い 場 合 は 、

info::device::native_vector_width_float

info::device::preferred_vector_width_half は 0 を返します。

info::device::native_vector_width_double
info::device::native_vector_width_half
info::device::max_clock_frequency

uint32_t

SYCL device の最大クロック周波数を MHz で返します。

info::device::address_bits

uint32_t

ビット単位の符号なし整数として指定されるデフォルト計算デバ
イスのアドレス空間サイズを返します。32 または 64 のいずれかでなければなりません。

info::device::max_mem_alloc_size

uint64_t

メモリー・オブジェクト割り当ての最大サイズをバイト単位で返します。SYCL device がデバイスタイプ info::device_type::custom ではない場合、最小値は max (info::device::global_mem_size の1/4、128*1024*1024 ) です。

info::device::image_support

bool

非推奨です。
device::has(aspect::image) と同じ値を返します。

info::device::max_read_image_args

uint32_t

カーネルから読み取ることができる同時イメージ・オブジェクトの最大数を返します。SYCL device に aspect::image がある場合の最小値は 128 です。

info::device::max_write_image_args

uint32_t

カーネルへ書き込むことができる同時イメージ・オブジェクトの最大数を返します。SYCL device に aspect::image がある場合の最小値は 8 です。

第 4 章 SYCL プログラミング・インターフェイス | 71

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::image2d_max_widthsize_t2D イメージまたは 3D イメージの最大幅をピクセル単位で返します。SYCL device に aspect::image がある場合の最小値は8192 です。

info::device::image2d_max_heightsize_t2D イメージの最大高をピクセル単位で返します。SYCL device に
aspect::image がある場合の最小値は 8192 です。

info::device::image3d_max_widthsize_t3D イメージの最大幅をピクセル単位で返します。SYCL device に
aspect::image がある場合の最小値は 2048 です。

info::device::image3d_max_heightsize_t3D イメージの最大高をピクセル単位で返します。SYCL device に
aspect::image がある場合の最小値は 2048 です。

info::device::image3d_max_depth

size_t3D イメージの最大深度をピクセル単位で返します。SYCL deviceに aspect::image がある場合の最小値は 2048 です。

info::device::image_max_buffer_size

size_tバッファー・オブジェクトから作成された 1D イメージのピクセル数を返します。SYCL device に aspect::image がある場合の最小値は 65536 です。この機能は SYCL でサポートされていないた
め、情報は OpenCL との相互運用性のみを目的とすることに注意
してください。

info::device::max_samplers

uint32_t

カーネルで使用できるサンプラーの最大数を返します。 SYCL
device に aspect::image がある場合の最小値は 16 です。

info::device::max_parameter_size

size_tカーネルに渡すことができる引数の最大サイズをバイト単位で返し ま す 。 SYCL device が デ バ イ ス タ イ プ

info::device_

type::custom でない場合、最小値は 1024 です。最小値である場合、カーネルに渡すことが可能な引数の最大数は 128 となります。
info::device::mem_base_addr_alignuint32_t

SYCL device が デバイスタイプ info::device_type::custom ではない場合、サポートされる SYCL ビルトイン・データ・タイプの最小値をビット単位で返します。

72 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::half_fp_config

std::vector<info::

こ の SYCL device の 半 精 度 浮 動 小 数 点 機 能 を 記 述 す る

fp_config>

info::fp_config の std::vector を返します。std::vector には、次の値が 0 個以上含まれる可能性があります。

• info::fp_config::denorm: デノーマルがサポートされます。
• info::fp_config::inf_nan: INF と QNaN がサポートされます。
• info::fp_config::round_to_nearest: 最も近い偶数への丸めモードがサポートされます。

• info::fp_config::round_to_zero: ゼロへの丸めモードがサポートされます。

• info::fp_config::round_to_inf: 正および負の無限大への丸めモードがサポートされます。

• info::fp_config::fma: IEEE754-2008 乗算加算の融合がサポートされます。

• info::fp_config::correctly_rounded_divide_sqrt: 除算と平方根が IEEE754 仕様で定義されるように正確に丸められます。このプロパティーは非推奨です。

• info::fp_config::soft_float: 基本的な浮動小数点演算 (加算、減算、乗算など) がソフトウェアで実装されます。
SYCL device で 半 精 度 が サ ポ ー ト さ れ る 場 合 (device に
aspect::fp16 がある)、最小浮動小数点機能はありません。半精度がサポートされない場合、戻り値 std::vector は空である必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 73

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

info::device::single_fp_config

std::vector<info:: こ の SYCL device の 単 精 度 浮 動 小 数 点 機 能 を 記 述 す る
fp_config>

説明info::fp_config の std::vector を返します。std::vector には、次の値が 1 個以上含まれる可能性があります。

• info::fp_config::denorm: デノーマルがサポートされます。
• info::fp_config::inf_nan: INF と QNaN がサポートされます。
• info::fp_config::round_to_nearest: 最も近い偶数への丸めモードがサポートされます。

• info::fp_config::round_to_zero: ゼロへの丸めモードがサポートされます。

• info::fp_config::round_to_inf: 正および負の無限大への丸めモードがサポートされます。

• info::fp_config::fma: IEEE754-2008 乗算加算の融合がサポートされます。

• info::fp_config::correctly_rounded_divide_sqrt: 除算と平方根が IEEE754 仕様で定義されるように正確に丸められます。このプロパティーは非推奨です。

• info::fp_config::soft_float: 基本的な浮動小数点演算 (加算、減算、乗算など) がソフトウェアで実装されます。
SYCL device が info::device_type::custom タイプでない場合、最小の浮動小数点機能は info::fp_config::round_to_nearest
および info::fp_config::inf_nan である必要があります。

74 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

info::device::double_fp_config

std::vector<info:: こ の SYCL device の 倍 精 度 浮 動 小 数 点 機 能 を 記 述 す る
fp_config>

説明info::fp_config の std::vector を返します。std::vector には、次の値が 0 個以上含まれる可能性があります。

• info::fp_config::denorm: デノーマルがサポートされます。
• info::fp_config::inf_nan: INF と NaN がサポートされます。
• info::fp_config::round_to_nearest: 最も近い偶数への丸めモードがサポートされます。

• info::fp_config::round_to_zero: ゼロへの丸めモードがサポートされます。

• info::fp_config::round_to_inf: 正および負の無限大への丸めモードがサポートされます。

• info::fp_config::fma: IEEE754-2008 乗算加算の融合がサポートされます。

• info::fp_config::soft_float: 基本的な浮動小数点演算 (加算、減算、乗算など) がソフトウェアで実装されます。
SYCL device で倍精度がサポートされ (device が aspect::fp64 を持つ)、SYCL device のタイプが info::device_type::custom でな
い 場 合 、 最 小 浮 動 小 数 点 機 能 は 、 info::fp_config::fma 、
info::fp_config::round_to_nearest、info::fp_config::round_to_
zero、info::fp_config::round_to_inf、info::fp_config::inf_nan お
よび info::fp_config::denorm となります。倍精度がサポートされない場合、戻り値 std::vector は空である必要があります。
info::device::global_mem_cache_type

info::global_me

サポートされるグローバルメモリーのキャッシュタイプを返し

m_cache_type

ます。

info::device::global_mem_cache_line_siz uint32_t

グローバルメモリーのキャッシュラインのサイズをバイト単位で

e

返します。

info::device::global_mem_cache_size

uint64_t

グローバルメモリーのキャッシュサイズをバイト単位で返します。

info::device::global_mem_size

uint64_t

グローバル・デバイス・メモリーのサイズをバイト単位で返します。

info::device::max_constant_buffer_size

uint64_t

SYCL 2020 では非推奨です。定数バッファー割り当ての最大サイズ を バ イ ト 単 位 で 返 し ま す 。 SYCL device が デ バ イ ス タ イ プ
info::device_type::custom でない場合、最小値は 64KB です。

info::device::max_constant_args

uint32_t

SYCL 2020 では非推奨です。カーネルで宣言可能な定数引数の最大数を返します。SYCL device が info::device_type::custom
タイプでない場合、最小値は 8 です。

第 4 章 SYCL プログラミング・インターフェイス | 75

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::local_mem_type

info::local_mem

サポートされるローカルメモリーのタイプを返します。これは、_type

SRAM などの専用ローカル・メモリー・ストレージを意味する
info::local_mem_type::local ま た は info::local_mem_type::
global のいずれかです 。SYCL device が info::device_type::
custom で あ る場 合 、 ロ ー カル メ モ リ ー が サ ポ ー ト さ れ な い
info::local_mem_type::none であることもあります。

info::device::local_mem_size

uint64_t

ローカルメモリーのアリーナサイズをバイト単位で返します。
SYCL device が info::device_type::custom タイプでない場合、最小値は 32KB です。

info::device::error_correction_ supportbool

デバイスが計算デバイスメモリー (グローバルおよび定数) のアク
セスに対するエラー訂正を実装する場合、true を返します。デバ
イスがエラー訂正機能を実装していない場合、false を返します。

info::device::host_unified_memorybool

非推奨です。代わりに aspect::usm_* アスペクトのいずれかとdevice::has() を使用します。
デバイスとホストに統合メモリー・サブシステムがある場合はtrue を返し、それ以外は false を返します。

info::device::atomic_memory_order_cap

std::vector<me

デバイスのアトミック操作でサポートされるメモリー順序のセッ

abilities

mory_order>

トを返します。これは、relaxed (緩和される) が含まれることが保証されます。

info::device::atomic_fence_order_capabil std::vector<meデバイス上の atomic_fence でサポートされるメモリー順序のities

セットを返します。これは、relaxed、acquire、release、acq_rel

mory_order>が含まれることが保証されます。
info::device::atomic_memory_scope_cap std::vector<me

デバイスのアトミック操作でサポートされるメモリースコープのabilities

セットを返します。これには、work_group が含まれることが保証

mory_scope>されます。
info::device::atomic_fence_scope_capabi std::vector<meデバイス上の atomic_fence でサポートされるメモリースコープ

litiesのセットを返します。これには、work_group が含まれることが保mory_scope>

証されます。
info::device::profiling_timer_resolution

size_tデバイスタイマーの精度をナノ秒単位で返します。

info::device::is_endian_littlebool

非推奨です。代わりにホストシステムのバイト順序を確認します。
ホストとデバイスのバイト順序は同一でなければなりません。
SYCL device がリトル・エンディアン・デバイスである場合は true
を返し、それ以外は false を返します。

info::device::is_availablebool

SYCL device が利用可能な場合は true を返し、利用できない場
合は false を返します。

76 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::is_compiler_availablebool

非推奨です。
device::has(aspect::online_compiler) と同じ値を返します。

info::device::is_linker_availablebool

非推奨です。
device::has(aspect::online_linker) と同じ値を返します。

info::device::execution_capabilities

std::vector<info:: サポートされる実行機能を示す info::execution_capability のexecution_capa

std::vector を返します。SYCL は info::execution_capability::

bility>exec_kernel のみをサポートするため、情報は OpenCL との相互運用性のみを目的とすることに注意してください。

info::device::queue_profilingbool

非推奨です。
device::has(aspect::queue_profiling) と同じ値を返します。

info::device::built_in_kernel_ids

info::device::built_in_kernels

std::vector<kern SYCL device でサポートされるビルトインカーネル識別子の
el_id>

std::vector を返します。

std::vector<std::

非推奨です。代わりに info::device::built_in_kernel_ids を使用

string>

します。
SYCL device でサポートされるビルトイン OpenCL カーネルのstd::vector を返します。

info::device::platform

platform

SYCL device に関連付けられている SYCL platform を返します。

info::device::name

std::string

SYCL device のデバイス名を返します。

info::device::vendor

std::string

SYCL device のベンダーを返します。

info::device::driver_version

std::string

バックエンド・ソフトウェア・ドライバーのバージョン示すベンダー
定義の文字列を返します。

info::device::profile

std::string

SYCL 2020 では非推奨です。OpenCL バックエンドを使用する
場合にのみサポートされます (付録 C を参照)。バックエンドがOpenCL でないデバイスで使用されると、errc::invalid エラー
コードで例外をスローします。
戻り値は次のいずれかの文字列です。

• FULL_PROFILE - デバイスが OpenCL 仕様をサポートする
場合 (コア仕様の一部として定義される機能であり、拡張機
能のサポートは必要ありません)。

• EMBEDDED_PROFILE - デバイスが OpenCL 組み込みプ
ロファイルをサポートする場合。
info::device::version

std::string

バックエンドのデバイスバージョンを返します。

第 4 章 SYCL プログラミング・インターフェイス | 77

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::backend_version

std::string

デバイスに関連付けられる SYCL バックエンドのバージョンを示す文字列を返します。この値は、デバイスに関連付けられている
SYCL バックエンド仕様で定義されています。

info::device::aspects

std::vector<aspe SYCL device でサポートされるアスペクト値の std::vector を返
ct>

78 | 第 4 章 SYCL プログラミング・インターフェイス

します。

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::extensions

std::vector

非推奨。代わりに info::device::aspects を使用します。

<std::string>

SYCL device でサポートされる拡張名 (スペースは含まれません)の std::vector を返します。戻り値の拡張名は、ベンダー定義の拡
張名と次に示す Khronos が承認する拡張名のいずれかです。

• cl_khr_int64_base_atomics• cl_khr_int64_extended_atomics• cl_khr_3d_image_writes• cl_khr_fp16• cl_khr_gl_sharing• cl_khr_gl_event• cl_khr_d3d10_sharing• cl_khr_dx9_media_sharing• cl_khr_d3d11_sharing• cl_khr_depth_images• cl_khr_gl_depth_images• cl_khr_gl_msaa_sharing• cl_khr_image2d_from_buffer• cl_khr_initialize_memory• cl_khr_context_abort• cl_khr_spir
SYCL device が OpenCL デバイスである場合、OpenCL 1.2 をサポートするすべてのデバイスは Khronos が承認する次の拡張名を返す必要があります。

• cl_khr_global_int32_base_atomics• cl_khr_global_int32_extended_atomics• cl_khr_local_int32_base_atomics• cl_khr_local_int32_extended_atomics• cl_khr_byte_addressable_store• cl_khr_fp64 (倍精度がサポートされる場合の下位互換のため)
これら拡張機能の詳細については、OpenCL 1.2 の拡張機能仕様をご覧ください。

第 4 章 SYCL プログラミング・インターフェイス | 79

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::printf_buffer_size

size_tSYCL 2020 では非推奨です。
カーネルの printf 呼び出しの出力を保持する内部バッファーの最大サイズを返します。info::device::profile が SYCL device に対し true を返す場合、最小値は 1MB です。

info::device::preferred_interop_user_syn bool

SYCL 2020 では非推奨です。OpenCL バックエンドを使用する

c

場合にのみサポートされます (付録 C を参照)。
OpenCL と DirectX などほかの API との間でメモリー・オブジェク
トを共有する際に、SYCL device の設定がユーザーによって同期される場合は true を返します。デバイス/実装に OpenCL と
DirectX などの API との間で共有されるメモリー・オブジェクトを同期するパフォーマンス・パスがある場合は false を返します。

info::device::parent_device

device

これがサブデバイスである場合、このサブデバイスの親 SYCL
device を返します。SYCL device がサブデバイスでない場合、
errc::invalid エラーコードで例外をスローする必要があります。

info::device::partition_max_sub_devices

uint32_t

SYCL device がパーティション化されている際に作成可能なサブデバイスの最大数を返します。戻り値は、info::device::device_
max_compute_units が返す値を超えることはできません。

info::device::partition_properties

std::vector<info:: SYCL device でサポートされるパーティション・プロパティーを
partition_proper info::partition_property のベクトルで返します。デバイスがパーty>

ティション・プロパティーに沿って 2 つ以上のサブデバイスにパーティション化できる場合にのみ、要素がベクトルで返されます。

info::device::partition_affinity_domains

std::vector<info:: info::partition_property::partition_by_affinity_domain

でpartition_affinity パーティション化する際に、SYCL device でサポートされるパー_domain>

ティション・アフィニティー・ドメインの std::vector を返します。
デバイスがパーティション・プロパティーに沿って 2 つ以上のサブデバイスにパーティション化できる場合にのみ、要素がベクトルで返されます。

info::device::partition_type_property

info::partition_pr SYCL device のパーティション・プロパティーを返します。SYCL
opertydevice がサブデバイスでない場合、戻り値は info::partition_
property::no_partition である必要があり、それ以外は次のいずれかの値になります。

• info::partition_property::partition_equally• info::partition_property::partition_by_counts• info::partition_property::partition_by_affinity_domain

80 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

デバイス記述子

戻り値

説明

info::device::partition_type_affinity_dom info::partition_af SYCL device のパーティション・プロパティー・ドメインを返しまainfinity_domain

す。SYCL device がサブデバイスでない場合、またはサブデバイ
ス が info::partition_type::partition_by_affinity_domain で
パーティション化されていない場合、戻り値は info::partition_affinity_domain::not_applicable である必要があり、それ以外
は次のいずれかの値になります。

• info::partition_affinity_domain::numa• info::partition_affinity_domain::L4_cache• info::partition_affinity_domain::L3_cache• info::partition_affinity_domain::L2_cache• info::partition_affinity_domain::L1_cache

4.6.4.3. デバイスアスペクト
すべての SYCL デバイスは、device の特性を識別するアスペクトを持ちます。アスペクトは enum class aspect 列挙で定義されます。
1.

namespace sycl {2.
3.

enum class aspect ： /* 未定義 */ {

4.

cpu,

5.

gpu,

6.

accelerator,

7.

custom,8.

emulated,9.

host_debuggable,

10.

fp16,

11.

fp64,

12.

atomic64,

13.

image,

14.

online_compiler,

15.

online_linker,

16.

queue_profiling,17.

usm_device_allocations,18.

usm_host_allocations,19.

usm_atomic_host_allocations,20.

usm_shared_allocations,21.

usm_atomic_shared_allocations,

22.
23.

usm_system_allocations
};

24.
25.

} // namespace sycl

SYCL アプリケーションは、device がオプション機能をサポートするかどうかを判断するため、device::has() を使用して device のアス
ペクトを照会できます。表 26 にコア SYCL 仕様で定義されるアスペクトとそれぞれに対応するオプション機能を示します。バックエンドと拡張機能は、追加のアスペクトとオプションのデバイス機能を提供する場合もあります。その場合、SYCL バックエンド仕様のドキュ
メント、または拡張仕様のドキュメントにそれらが記載されます。

第 4 章 SYCL プログラミング・インターフェイス | 81

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
表 26. コア SYCL 仕様で定義されるデバイスアスペクト
アスペクト

説明

aspect::cpu

CPU で実行されるデバイス。この aspect のデバイスには、デバイ
スタイプ info::device_type::cpu があります。

aspect::gpu

3D グラフィックｽをアクセラレートするために使用可能なデバイ
ス で す 。 こ の aspect の デ バ イ ス に は 、 デ バ イ ス タ イ プ
info::device_type::gpu があります。

aspect::accelerator

通信を行うため周辺機器に相互接続可能な専用アクセラレー
ター・デバイスです。この aspect のデバイスには、デバイスタイプ
info::device_type::accelerator があります。

aspect::custom

SYCL API を利用できる専用アクセラレーターですが、プログラム
可能なカーネルをデバイスにディスパッチすることはできません。
固定機能のみが利用できます。3.9.7 節を参照してください。このaspect の デ バ イ ス に は 、 デ バ イ ス タ イ プ info::device_
type::custom があります。

aspect::emulated

デバイスがエミュレートされていることを示します。このアスペクトを持つデバイスは、パフォーマンスを目的としたものではなく、エミュレーションやプロファイルなどに使用されます。このアスペ
クトの正確な定義は、SYCL 実装ではオープンのままです。
例えば、ベンダーはハードウェア FPGA デバイスとソフトウェア・エミュレーション FPGA の両方をサポートすることがあります。この場合、エミュレートされた FPGA はハードウェアと同じ機能を備えていますが、実行速度が遅くプロファイルや診断機能を提供します。この場合、ア
プリケーションのデバイスセレクターは、
aspect::emulated を使用して 2 つを区別できます。

aspect::host_debuggable

このデバイスで実行されるカーネルは、SYCL 実装が存在するホストシステムで標準デバッガーを使用してデバッグできます。このアスペクトの正確な定義は、SYCL 実装ではオープンのままです。

aspect::fp16

デバイスに送信されたカーネルが sycl::half データタイプを利用する可能性があることを示します。

aspect::fp64

デバイスに送信されたカーネルが double データタイプを利用する可能性があることを示します。

aspect::atomic64

デバイスに送信されたカーネルが 64 ビットアトミック操作を行う可能性があることを示します。

82 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

アスペクト

説明

aspect::image

デバイスがイメージをサポートすることを示します。

aspect::online_compiler

デバイスがデバイスコードのオンラインコンパイルをサポートすることを示します。このアスペクトを持つデバイスは、4.11.11 節
で定義される build() および compile() 関数をサポートします。

aspect::online_linker

デバイスがデバイスコードのオンラインリンクをサポートすることを示します。このアスペクトを持つデバイスは、4.11.11 節で定義される link() 関数をサポートします。このアスペクトを持つデバイスはまた、aspect::online_compiler を持ちます。

aspect::queue_profiling

デバイスが property::queue::enable_profiling を介したキューのプロファイルをサポートすることを示します。

aspect::usm_device_allocations

4.8 節で説明するように、デバイスが明示的な USM 割り当てをサポートすることを示します。

aspect::usm_host_allocations

デバイスが usm::alloc::host を使用して割り当てられた USM メ
モリーにアクセスできることを示します。デバイスは、
aspect::usm_atomic_host_allocations もサポートされている場合にのみ、ホスト割り当てのアトミック更新をサポートします(4.8 節を参照)。

aspect::usm_atomic_host_allocations

デバイスが usm::alloc::host を使用して割り当てられた USM メ
モリーをサポートすることを示します。ホストとデバイスは、ホスト割り当てに同時アクセスしてアトミックに更新する場合があります (4.8 節を参照)。

aspect::usm_shared_allocations

デバイスが usm::alloc::shared を使用して同じデバイスに割り当てられた USM メモリーをサポートすることを示します。共有割り
当 て の 同 時 ア ク セ ス と ア ト ミ ッ ク 更 新 は 、 aspect::usm_
atomic_shared_allocations もサポートされる場合にのみ利用できます (4.8 節を参照)。

aspect::usm_atomic_shared_allocations

デバイスが usm::alloc::shared を使用して割り当てられた USM
メモリーをサポートすることを示します。この機能をサポートする
同一コンテキスト内のホストとデバイスは、共有割り当てに同時にアクセスしてアトミック更新を行う場合があります。割り当てはホストとデバイス間で自由に移行できます (4.8 節を参照)。

aspect::usm_system_allocations

デバイスの usm::alloc::shared 割り当てに、SYCL USM メカニズ
ムに代わってシステム・アロケーターを利用できることを示します(4.8 節を参照)。

実装は、アプリケーションがコンパイル時にアスペクトの照会に使用できる 2 つの特性を提供します。any_device_has<aspect> 特性
は、コンパイル環境が指定するアスペクトを持つデバイスをサポートする場合 std::true_type から継承し、アスペクトを持つデバイスが第 4 章 SYCL プログラミング・インターフェイス | 83

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
ない場合は std::false_type から継承します。all_devices_have<aspect> 特性は、コンパイル環境でサポートされるすべてのデバイスに指定されたアスペクトがある場合 std::true_type から継承し、いずれかのデバイスにアスペクトがない場合は std::false_type から継
承します。
1.

namespace sycl {2.
3.

template <aspect Aspect> struct any_device_has;4.

template <aspect Aspect> struct all_devices_have;

5.
6.

template <aspect A> inline constexpr bool any_device_has_v = any_device_has<A>::value;

7.

template <aspect A> inline constexpr bool all_devices_have_v = all_devices_have<A>::value;

8.
9.

}

アプリケーションはこれらの特性を使用してコードサイズを軽減できます。次の例では、これらの特性を使用していずれのデバイスでもサポートされないデバイス機能のテンプレート化されたカーネルのインスタンス化を回避する方法を示しています。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

3.
4.

constexpr int N = 512;5.
6.

template<bool HasFp16>

7.

class MyKernel {8.

public:9.

void operator()(id<1> i) {10.

if constexpr (HasFp16) {11.

// sycl::half タイプを使用するアルゴリズム

12.

} else {13.

// sycl::half をサポートしないデバイスのフォールバック・コード

14.

}

15.
16.

}
};

17.
18.

int main() {19.

queue myQueue;

20.

myQueue.submit([&](handler& cgh) {21.

device dev = myQueue.get_device();22.

if (dev.has(aspect::fp16)) {23.

cgh.parallel_for(range{N}, MyKernel<any_device_has_v<aspect::fp16>>{});

24.

} else {25.

cgh.parallel_for(range{N}, MyKernel<all_devices_have_v<aspect::fp16>>{});

26.

}

27.

});

28.
29.

myQueue.wait();30.

}

カーネル関数 MyKernel は、デバイスにアスペクト aspect::fp16 があるかに応じて異なるアルゴリズムを適用するようにテンプレー
ト化されており、 dev.has() を呼び出してデバイスの機能に一致するカーネル関数のインスタンス化が選択されます 。ただし、
any_device_has_v と all_devices_have_v を使用すると、カーネル関数の不要なインスタンス化を回避できます。例えば、コンパイル
環境で aspect::fp16 がサポートされていない場合、any_device_has_v<aspect::fp16> は false であり、カーネル関数は sycl::half
タイプをサポートするようにインスタンス化されることはありません。

84 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

ほかの特性と同様に、any_device_has_v と all_devices_have_v の値は、SYCL アプリケーションのすべてで均一な値を保持します。実装が SMCP を使用する場合、すべてのコンパイラー・パスは、特定のアスペクト特性の特殊化を同じ方法で定義して、そのコンパイラー・パスのデバイスがアスペクトをサポートするかどうかは考慮しません。そのため、any_device_has と all_devices_have を使用して特定のデバイスがアスペクトをサポートするかどうかを判断することはできません。代わりに、アプリケーションは device::has() または platform::has() を使用します。

実装では、サポートするデバイスセットに影響するコマンドライン・オプションを提供することを選択できます。その場合、コマンドライン・オプションも特性に影響します。例えば、実装で aspect::accelerator を無効にするコマンド
ラ イ ン ・ オ プ シ ョ ン が 用 意 さ れ て い る 場 合 、 そ の オ プ シ ョ ン が 指 定 さ れ る と
any_device_has_v<aspect::accelerator> 特性は false になります。

4.6.5. キュークラス
SYCL queue クラスは、SYCL デバイス上のカーネルをスケジュールする単一のキューをカプセル化します。
SYCL queue を使用して submit メンバー関数送信により SYCL ランタイムで実行されるコマンドグループを送信できます。
queue クラスのすべてのメンバー関数は同期的であり、エラーは同期 SYCL 例外をスローすることで処理されます。submit メンバー
関数はコマンドグループを非同期にスケジュールするため、コマンドグループの送信エラーが発生した場合、同期 SYCL 例外をスローして処理できます。4.13 節で説明されるように、送信後のコマンドグループからの例外は、特定のタイミングで非同期エラーを
async_handler に渡すことで処理されます。
SYCL queue は wait または wait_and_throw を呼び出すことで、送信したコマンドグループを待機できます。
SYCL queue クラスのデフォルト・コンストラクターは、default_selector_v から返された SYCL device に基づいてキューを構築します (4.6.1.1 節を参照)。ほかのすべてのコンストラクターは、与えられたパラメーターによってキューを構築します。すべてのコンストラ
クターは、キューの構築を容易にするため SYCL platform、device および context を暗黙的に作成します。
各コンストラクターは、最後のパラメーターとしてオプションの SYCL property_list を受け取って、SYCL queue にプロパティーを提供します。
SYCL queue は、キューに未完了のコマンドが残っている場合でも、破棄されることがあります。これにより未完了のコマンドがブロッ
クされることはなく、キューが破棄されなかった場合と同じように、その要求が満たされた時点で実行が開始されます。それらのコマンドのイベント・オブジェクトは、コマンドが完了したときに通常の方法でシグナルが送信されます。キューに関連するリソースは、最後のコマンドが完了するまでに解放されます。
SYCL queue クラスは共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.6.5.1. キュー・インターフェイスSYCL queue クラスの概要を以下に示します。SYCL queue クラスのコンストラクターとメンバー関数を表 27 と表 28 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 を参照してください。
一部のキューのメンバー関数は、handler クラスのメンバー関数へのショートカットです。4.6.5.2 節にリストを示します。
1.

namespace sycl {2.

class queue {3.

public:4.

explicit queue(const property_list& propList = {});

第 4 章 SYCL プログラミング・インターフェイス | 85

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
5.
6.
7.

explicit queue(const async_handler& asyncHandler,
const property_list& propList = {});

8.
9.

template <typename DeviceSelector>

10.

explicit queue(const DeviceSelector& deviceSelector,

11.

const property_list& propList = {});

12.
13.

template <typename DeviceSelector>

14.

explicit queue(const DeviceSelector& deviceSelector,

15.

const async_handler& asyncHandler,

16.

const property_list& propList = {});

17.
18.

explicit queue(const device& syclDevice, const property_list& propList = {});

19.
20.
21.

explicit queue(const device& syclDevice, const async_handler& asyncHandler,
const property_list& propList = {});

22.
23.

template <typename DeviceSelector>

24.

explicit queue(const context& syclContext,

25.

const DeviceSelector& deviceSelector,

26.

const property_list& propList = {});

27.
28.

template <typename DeviceSelector>

29.

explicit queue(const context& syclContext,

30.

const DeviceSelector& deviceSelector,

31.

const async_handler& asyncHandler,

32.

const property_list& propList = {});

33.
34.
35.

explicit queue(const context& syclContext, const device& syclDevice,
const property_list& propList = {});

36.
37.

explicit queue(const context& syclContext, const device& syclDevice,38.

const async_handler& asyncHandler,

39.

const property_list& propList = {});

40.
41.

/* -- 共通インターフェイスのメンバー -- */

42.
43.

/* -- プロパティー・インターフェイスのメンバー -- */

44.
45.

backend get_backend() const noexcept;

46.
47.

context get_context() const;

48.
49.

device get_device() const;

50.
51.

bool is_in_order() const;

52.
53.

template <typename Param> typename Param::return_type get_info() const;

54.
55.

template <typename Param>

56.

typename Param::return_type get_backend_info() const;

86 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
57.
58.

template <typename T>

59.

event submit(T cgf);

60.
61.

template <typename T>

62.

event submit(T cgf, const queue& secondaryQueue);

63.
64.

void wait();

65.
66.

void wait_and_throw();

67.
68.

void throw_asynchronous();

69.
70.

/* -- ショートカット -- */

71.
72.

template <typename KernelName, typename KernelType>73.

event single_task(const KernelType& kernelFunc);

74.
75.

template <typename KernelName, typename KernelType>76.

event single_task(event depEvent, const KernelType& kernelFunc);

77.
78.

template <typename KernelName, typename KernelType>79.

event single_task(const std::vector<event>& depEvents,

80.

const KernelType& kernelFunc);

81.
82.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

83.

template <typename KernelName, int Dims, typename...Rest>

84.

event parallel_for(range<Dims> numWorkItems,

85.

Rest&&... rest);

86.
87.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

88.

template <typename KernelName, int Dims, typename...Rest>

89.

event parallel_for(range<Dims> numWorkItems, event depEvent,90.

Rest&&... rest);

91.
92.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

93.

template <typename KernelName, int Dims, typename...Rest>

94.

event parallel_for(range<Dims> numWorkItems,

95.

const std::vector<event>& depEvents,

96.

Rest&&... rest);

97.
98.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

99.

template <typename KernelName, int Dims, typename...Rest>

100.

event parallel_for(nd_range<Dims> executionRange,

101.

Rest&&... rest);

102.
103.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

104.

template <typename KernelName, int Dims, typename...Rest>

105.

event parallel_for(nd_range<Dims> executionRange,

106.

event depEvent,107.

Rest&&... rest);

108.

第 4 章 SYCL プログラミング・インターフェイス | 87

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
109.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

110.

template <typename KernelName, int Dims, typename...Rest>

111.

event parallel_for(nd_range<Dims> executionRange,

112.

const std::vector<event>& depEvents,

113.

Rest&&... rest);

114.
115.

/* -- USM 関数 -- */

116.
117.

event memcpy(void* dest, const void* src, size_t numBytes);

118.

event memcpy(void* dest, const void* src, size_t numBytes,

119.
120.
121.

event depEvent);
event memcpy(void* dest, const void* src, size_t numBytes,
const std::vector<event>& depEvents);

122.
123.

template <typename T>

124.

event copy(const T* src, T* dest, size_t count);

125.

template <typename T>

126.

event copy(const T* src, T* dest , size_t count,

127.

event depEvent);

128.

template <typename T>

129.

event copy(const T*src, T* dest , size_t count,130.

const std::vector<event>& depEvents);

131.
132.

event memset(void* ptr, int value, size_t numBytes);

133.

event memset(void* ptr, int value, size_t numBytes,

134.
135.
136.

event depEvent);
event memset(void* ptr, int value, size_t numBytes,
const std::vector<event>& depEvents);

137.
138.

template <typename T>

139.

event fill(void* ptr, const T& pattern, size_t count);

140.
141.

template <typename T>
event fill(void* ptr, const T& pattern, size_t count,

142.

event depEvent);

143.

template <typename T>

144.

event fill(void* ptr, const T& pattern, size_t count,145.

const std::vector<event>& depEvents);

146.
147.

event prefetch(void* ptr, size_t numBytes);

148.

event prefetch(void* ptr, size_t numBytes,

149.
150.
151.

event depEvent);
event prefetch(void* ptr, size_t numBytes,
const std::vector<event>& depEvents);

152.
153.

event mem_advise(void* ptr, size_t numBytes, int advice);154.

event mem_advise(void* ptr, size_t numBytes, int advice,

155.

event depEvent);

156.

event mem_advise(void* ptr, size_t numBytes, int advice,157.

const std::vector<event>& depEvents);

158.
159.

/// プレースホルダー・アクセサーのショートカット

160.

88 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
161.

// 明示的なコピー関数

162.
163.

template <typename SｒcT, int SrcDims, access_mode SrcMode, target SrcTgt,

164.

access::placeholder IsPlaceholder, typename DestT>

165.

event copy(accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsPlaceholder> src,

166.

std::shared_ptr<DestT> dest);

167.
168.

template <typename SrcT, typename DestT, int DestDims,

169.

access_mode DestMode, target DestTgt,

170.

access::placeholder IsPlaceholder>

171.

event

172.

copy(std::shared_ptr<SrcT> src,

173.

accessor<DestT, DestDims , DestMode , DestTgt, IsPlaceholder> dest);

174.
175.

template <typename SrcT, int SrcDims, access_mode SrcMode, target SrcTgt,

176.

access::placeholder IsPlaceholder, typename DestT>

177.

event copy(accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsPlaceholder> src,

178.

DestT* dest);

179.
180.

template <typename SrcT, typename DestT, int DestDims ,181.

access_mode DestMode , target DestTgt,

182.

access::placeholder IsPlaceholder>

183.

event

184.

copy(const SrcT* src,

185.

accessor<DestT, DestDims , DestMode , DestTgt, IsPlaceholder> dest);

186.
187.

template <typename SrcT, int SrcDims, access_mode SrcMode, target SrcTgt,

188.

access::placeholder IsPlaceholder_src, typename DestT,189.

int DestDims , access_mode DestMode , target DestTgt,

190.

access::placeholder IsPlaceholder_dest>

191.

event copy(

192.

accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsPlaceholder_src> src,

193.

accessor< DestT, DestDims , DestMode , DestTgt, IsPlaceholder_dest > dest);

194.
195.

template <typename T, int Dims, access_mode Mode, target Tgt,

196.

access::placeholder IsPlaceholder>

197.

event update_host(accessor<T, Dims, Mode, Tgt, IsPlaceholder> acc);

198.
199.

template <typename T, int Dims, access_mode Mode, target Tgt,

200.

access::placeholder IsPlaceholder>

201.

event fill(accessor<T, Dims, Mode, Tgt, IsPlaceholder> dest, const T& src);

202.

};

203.

} // namespace sycl

第 4 章 SYCL プログラミング・インターフェイス | 89

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
表 27. queue クラスのコンストラクター
コンストラクター

説明

explicit queue(const property_list& propList = {})default_selector_v から構築されたデバイスを使用して、SYCL
queue インスタンスを構築します。property_list のインスタンス
を介して、構築された SYCL queue に 0 個以上のプロパティーを供給できます。

explicit queue(const async_handler& asyncHandler,
const property_list& propList = {})default_selector_v か ら 構 築 さ れ た デ バ イ ス を 使 用 し て 、
async_handler で SYCL queue インスタンスを構築します。
property_list のインスタンスを介して、構築された SYCL queueに 0 個以上のプロパティーを提供できます。

template <typename DeviceSelector>

デバイスセレクターのパラメーターから返されるデバイスを使用

explicit queue(const DeviceSelector& deviceSelector,

して SYCL queue インスタンスを作成します。property_list のイ

const property_list& propList = {})ンスタンスを介して、構築された SYCL queue に 0 個以上のプロ
パティーを提供できます。

template <typename DeviceSelector>

デバイスセレクターのパラメーターから返されるデバイスを使用

explicit queue(const DeviceSelector& deviceSelector,

して、async_handler で SYCL queue インスタンスを作成しま

const async_handler& asyncHandler,

す。property_list のインスタンスを介して、構築された SYCL

const property_list& propList = {})queue に 0 個以上のプロパティーを提供できます。

explicit queue(const device& syclDevice,

syclDevice を使用して SYCL queue インスタンスを作成します。

const property_list& propList = {})property_list のインスタンスを介して、構築された SYCL queueに 0 個以上のプロパティーを提供できます。

explicit queue(const device& syclDevice,

syclDevice を使用して async_handler で SYCL queue インス

const async_handler& asyncHandler,

タンスを作成します。property_list のインスタンスを介して、構const property_list& propList = {})築された SYCL queue に 0 個以上のプロパティーを提供できます。

template <typename DeviceSelector>

デバイスセレクターのパラメーターから返されるデバイスを使用

explicit queue(const context& syclContext,

して、syclContext に関連付けられた SYCL queue インスタンス

const DeviceSelector& deviceSelector,

を作成します。syclContext が deviceSelector が返す SYCL

const property_list& propList = {})device をカプセル化しない場合、errc::invalid エラーコードで例
外をスローする必要があります。property_list のインスタンスを介して、構築された SYCL queue に 0 個以上のプロパティーを提供できます。

template <typename DeviceSelector>

デバイスセレクターのパラメーターから返されるデバイスを使用

explicit queue(const context& syclContext,

して、syclContext に関連付けられた async_handler で SYCL

const DeviceSelector& deviceSelector,

queue イ ン ス タ ン ス を 作 成 し ま す 。 syclContext がconst async_handler& asyncHandler,

deviceSelector が返す SYCL device をカプセル化しない場合、const property_list& propList = {})errc::invalid エラーコードで例外をスローする必要があります。
property_list のインスタンスを介して、構築された SYCL queueに 0 個以上のプロパティーを提供できます。

90 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

コンストラクター

説明

explicit queue(const context& syclContext,

syclDevice を使用して SYCL queue インスタンスを構築します。

const device& syclDevice,

このデバイスは、syclContext に含まれるか、そのコンテキストに

const property_list& propList = {})含まれるデバイスの下位デバイスである必要があります。そうでない場合、この関数は errc::invalid エラーコードで例外をスローします。property_list のインスタンスを介して、構築された SYCL
queue に 0 個以上のプロパティーを供給できます。

explicit queue(const context& syclContext,

syclDevice を使用して SYCL queue インスタンスを構築します。

const device& syclDevice,

このデバイスは、syclContext に含まれるか、そのコンテキストに

const async_handler& asyncHandler,

含まれるデバイスの下位デバイスである必要があります。そうでconst property_list& propList = {})ない場合、この関数は errc::invalid エラーコードで同期例外をス
ローします。property_list のインスタンスを介して、構築された
SYCL queue に 0 個以上のプロパティーを供給できます。

表 28. queue クラスのメンバー関数
メンバー関数説明

backend get_backend() const noexcept

この queue に関連付けられている SYCL バックエンドを識別する backend を返します。

context get_context () const

SYCL queue のコンテキストを返します。SYCL 例外クラスを使用してエラーを報告します。戻り値は、get_info<info::queue::context>()が返す値と同じである必要があります。

device get_device () const

キューが関連付けられている SYCL デバイスを返します。SYCL
例外クラスを使用してエラーを報告します。戻り値は、get_info<info::queue::device>() が返す値と同じである必要があります。

bool is_in_order() const

SYCL queue が in_order プロパティーで作成された場合は trueを返します。has_property<property::queue::in_order>() と等価です。

void wait()

キューに投入されたすべてのタスクが完了するまでブロック待機を実行します。同期エラーは SYCL 例外を通して報告されます。

void wait_and_throw ()キューに投入されたすべてのタスクが完了するまでブロック待機を実行します。同期エラーは SYCL 例外を通して報告されます。
処理されていない非同期エラーは、キューまたは囲まれたコンテ
キストに関連付けられた async_handler に渡されます。キューまたは囲まれたコンテキストに関連付けられたユーザー定義のasync_handler がない場合、4.13.1.2 節で説明するように、実装
定義のデフォルト async_handler が呼び出されてエラーが処理されます。

第 4 章 SYCL プログラミング・インターフェイス | 91

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

void throw_asynchronous ()処理されていない非同期エラーがキューから生じたものかを確認し、生成されている場合はキューに関連付けられている
async_handler または囲まれたコンテキストに渡すことで報告されます。キューまたは囲まれたコンテキストに関連付けられた
ユーザー定義の async_handler がない場合、4.13.1.2 節で説明するように、実装定義のデフォルト async_handler が呼び出されてエラーが処理されます。

template <typename Param>

テンプレート・パラメーター Param で要求される情報の SYCL

typename Param::return_type get_info() const

queue を照会します。タイプエイリアス Param::return_type は、Param パラメーターに関連付けられたタイプを返すため、表 30の info パラメーターに従って定義する必要があります。

template <typename T> event submit(T cgf)

デバイスでの実行をスケジュールするため、コマンドグループ関
数オブジェクトをキューに送信します。

template <typename T>

デバイスでの実行をスケジュールするため、コマンドグループ関event submit(T cgf, queue& secondaryQueue)

数オブジェクトをキューに送信します。カーネルでエラーが発生すると、 コマンドグループ関数オブジェクト はセカンダリ ー・
キューで実行されるようにスケジュールされます。コマンドグ
ループ関数オブジェクトが投入されているキューに対応するイベ
ントを返します。

template <typename Param>

テンプレート・パラメーター Param が要求する SYCL バックエン

typename Param::return_type get_backend_info() const

ド固有の情報について SYCL queue を照会します。タイプエイリ
アス Param::return_type は、SYCL バックエンド仕様に従って定義する必要があります。Param に対応する SYCL バックエンド
が、queue に関連付けられる SYCL バックエンドと異なる場合、
errc::backend_mismatch エラーコードで例外をスローする必要があります。

4.6.5.2. キュー・ショートカット関数
キュー・ショートカット関数は、単一のコマンドで構成される暗黙のコマンドグループ handler によりコマンドグループを作成する
queue クラスのメンバー関数です。同じ署名を持つハンドラー・オブジェクトのメンバー関数を呼び出し (例えば、queue::single_task
は同じ引数で handler::single_task を呼び出す)、コマンドグループを送信します。署名による違いは戻り値のタイプにあります。
handler のメンバー関数は void を返しますが、対応するキュー・ショートカット関数は送信されたコマンドグループを示す event オブジェクトを返します。キュー・ショートカットは、暗黙のコマンドグループの handler::depends_on にイベントリストを渡すように待機するイベントリストを追加で取得できます。
キュー・ショートカットの完全なリストを表 29 に示します。ハンドラーのメンバー関数を表 131 に示します。
暗黙的に作成されたコマンドグループでアクセサーを取得することは許可されません。キュー・ショートカット関数 (single_task または parallel_for) がカーネルを起動する場合、カーネル内では USM ポインターのみが許可されます。ただし、カーネル以外の操作を実行するキュー・ショートカットには、引数として有効なプレースホルダー・アクセサーを指定できます。この場合、実行には追加の手順が必要であり、暗黙のコマンドグループ handler は、関数の引数として渡されるそれぞれの handler::require を呼び出します。

92 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
キュー・ショートカットの使い方を以下に示します。
1.

class MyKernel;

2.
3.

queue myQueue;

4.

auto usmPtr = malloc_device<int>(1024, myQueue); // USM ポインター

5.
6.

int* data = /* データへのポインター */;7.

buffer buf{data, 1024};8.

accessor acc{buf}; // プレースホルダー・アクセサー

9.
10.

// カーネルを起動するキューのショートカット

11.

myQueue.single_task<MyKernel>([=] {12.

// USM ポインターを許可、

13.

// アクセサーは不許可

14.
15.

usmPtr[0] = 0;
});

16.
17.

// プレースホルダー・アクセサーは自動的に登録されます18.

myQueue.copy(data, acc);

表 29. キュー・ショートカット関数
関数定義

関数タイプ

説明

template <typename KernelName, typename KernelType>

カーネル関数

handler::single_task(kernelFunc)

event single_task(const KernelType& kernelFunc)

を含むコマンドグループの送信に相当します。

template <typename KernelName, typename KernelType>

カーネル関数

event single_task(event depEvent,handler::depends_on(depEvent)およびconst KernelType& kernelFunc)

handler::single_task(kernelFunc)
を含むコマンドグループの送信に相当します。

template <typename KernelName, typename KernelType>

カーネル関数

event single_task(const std::vector<event>& depEvents,

handler::depends_on(depEvents)
およびconst KernelType& kernelFunc)

handler::single_task(kernelFunc)
を含むコマンドグループの送信に相当します。

template <typename KernelName, int Dimensions, typename...Rest>

カーネル関数

event parallel_for(range<Dimensions> numWorkItems,

ms, rest) を含むコマンドグループのRest&&... rest)
template <typename KernelName, int Dimensions, typename...Rest>
event parallel_for(range<Dimensions> numWorkItems,
event& depEvents, Rest&&... rest)

handler::parallel_for(numWorkIte
送信に相当します。

カーネル関数

handler::depends_on(depEvent)およびhandler::parallel_for(numWorkIte
ms, rest) を含むコマンドグループの送信に相当します。

第 4 章 SYCL プログラミング・インターフェイス | 93

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

関数定義

関数タイプ

説明

template <typename KernelName, int Dimensions, typename...Rest>

カーネル関数

handler::depends_on(depEvent)

event parallel_for(range<Dimensions> numWorkItems,

およびconst std::vector<event>& depEvents,

handler::parallel_for(numWorkIte

Rest&&... rest)

ms, rest) を含むコマンドグループの送信に相当します。

template <typename KernelName, int Dimensions, typename...Rest>

カーネル関数

event parallel_for(nd_range<Dimensions> executionRange,

nge, rest) を含むコマンドグループ

Rest&&... rest)
template <typename KernelName, int Dimensions, typename...Rest>

handler::parallel_for(executionRaの送信に相当します。

カーネル関数

event parallel_for(nd_range<Dimensions> executionRange,

handler::depends_on(depEvent)および

event depEvent, Rest&&... rest)

handler::parallel_for(executionRange, rest) を含むコマンドグループの送信に相当します。

template <typename KernelName, int Dimensions, typename...Rest>

カーネル関数

event parallel_for(nd_range<Dimensions> executionRange,

handler::depends_on(depEvent)およびconst std::vector<event>&depEvents,

handler::parallel_for(executionRa

Rest&&... rest)

nge, rest) を含むコマンドグループの送信に相当します。

event memcpy(void* dest, const void* src, size_t numBytes)

USM

handler::memcpy(dest, src,
numBytes) を含むコマンドグループの送信に相当します。

event memcpy(void* dest, const void* src, size_t numBytes,

USM

event depEvent)handler::depends_on(depEvent)および handler::memcpy(dest, src,
numBytes) を含むコマンドグループの送信に相当します。

event memcpy(void* dest, const void* src, size_t numBytes,

USM

const std::vector<event>& depEvents)

handler::depends_on(depEvent)および handler::memcpy(dest, src,
numBytes) を含むコマンドグループの送信に相当します。

template <typename T>

USM

event copy(const T* src, T* dest, size_t count)handler::copy(src, dest, count) を含むコマンドグループの送信に相当します。

template <typename T>
event copy(const T* src, T* dest, size_t count,
event depEvent)USM

handler::depends_on(depEvent)および handler::copy(src, dest,
count) を含むコマンドグループの送信に相当します。

94 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

関数定義

関数タイプ

説明

template <typename T>

USM

handler::depends_on(depEvent)

event copy(const T* src, T* dest, size_t count,および handler::copy(src, dest,

const std::vector<event>& depEvents)

count) を含むコマンドグループの送信に相当します。

event memset(void* ptr, int value, size_t numBytes)

USM

handler::memset(ptr, value,
numBytes) を含むコマンドグループの送信に相当します。

event memset(void* ptr, int value, size_t numBytes,

USM

event depEvent)handler::depends_on(depEvent)および handler::memset(ptr,value, numBytes) を含むコマンド
グループの送信に相当します。

event memset(void* ptr, int value, size_t numBytes,

USM

const std::vector<event>& depEvents)

handler::depends_on(depEvent)および handler::memset(ptr,value, numBytes) を含むコマンド
グループの送信に相当します。

template <typename T>

USM

event fill(void* ptr, const T& pattern, size_t count)handler::fill(ptr, pattern, count) を含むコマンドグループの送信に相当します。

template <typename T>

USM

event fill(void* ptr, const T& pattern, size_t count,handler::depends_on(depEvent)および handler::fill(ptr, pattern,

event depEvent)count) を含むコマンドグループの送信に相当します。

template <typename T>

USM

event fill(void* ptr, const T& pattern, size_t count,handler::depends_on(depEvent)および handler::fill(ptr, pattern,

const std::vector<event>& depEvents)

count) を含むコマンドグループの送信に相当します。

event prefetch(void* ptr, size_t numBytes)

USM

handler::prefetch(ptr, numBytes)
を含むコマンドグループの送信に相当します。

event prefetch(void* ptr, size_t numBytes,

USM

event depEvent)handler::depends_on(depEvent)および handler::prefetch(ptr,
numBytes) を含むコマンドグループの送信に相当します。

event prefetch(void* ptr, size_t numBytes,
const std::vector<event>& depEvents)

USM

handler::depends_on(depEvent)および handler::prefetch(ptr,
numBytes) を含むコマンドグループの送信に相当します。

第 4 章 SYCL プログラミング・インターフェイス | 95

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

関数定義

関数タイプ

説明

event mem_advise(void* ptr, size_t numBytes, int advice)USM

handler::mem_advise(ptr,
numBytes, advice) を含むコマンド
グループの送信に相当します。

event mem_advise(void* ptr, size_t numBytes, int advice,

USM

event depEvent)handler::depends_on(depEvent)および handler::mem_advise(ptr,
numBytes, advice) を含むコマンド
グループの送信に相当します。

event mem_advise(void* ptr, size_t numBytes, int advice,

USM

const std::vector<event>& depEvents)

handler::depends_on(depEvent)および handler::mem_advise(ptr,
numBytes, advice) を含むコマンド
グループの送信に相当します。

template <typename SrcT, int SrcDims, access_mode SrcMode,

明示的なコピー

handler::require(src) および

target SrcTgt, access::placeholder IsPlaceholder,

handler::copy(src, dest) を含むコ

typename DestT>

マンドグループの送信に相当します。

event copy(accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsPlaceholder>src, std::shared_ptr<DestT> dest);
template <typename SrcT, typename DestT, int DestDims,

明示的なコピー

handler::require(dest) および

access_mode DestMode, target DestTgt,

handler::copy(src, dest) を含むコ

access::placeholder IsPlaceholder>

マンドグループの送信に相当します。

event copy(std::shared_ptr<SrcT> src,
accessor<DestT, DestDims, DestMode, DestTgt, IsPlaceholder>dest);
template <typename SrcT, int SrcDims, access_mode SrcMode,

明示的なコピー

handler::require(src) および

target SrcTgt, access::placeholder IsPlaceholder,

handler::copy(src, dest) を含むコ

typename DestT>

マンドグループの送信に相当します。

event copy(accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsPlaceholder>src, DestT* dest);
template <typename SrcT, typename DestT, int DestDims,

明示的なコピー

handler::require(dest) および

access_mode DestMode, target DestTgt,

handler::copy(src, dest) を含むコ

access::placeholder IsPlaceholder>

マンドグループの送信に相当します。

event copy(const SrcT* src,
accessor<DestT, DestDims, DestMode, DestTgt, IsPlaceholder>dest);

96 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

関数定義

関数タイプ

説明

template <typename SrcT, int SrcDims, access_mode SrcMode,

明示的なコピー

handler::require(src)、

target SrcTgt, access::placeholder IsSrcPlaceholder,

handler::require(dest)、および

typename DestT, int DestDims, access_mode DestMode,handler::copy(src, dest) を含むコ

target DestTgt, access::placeholder IsDestPlaceholder>

マンドグループの送信に相当します。

event copy(
accessor<SrcT, SrcDims, SrcMode, SrcTgt, IsSrcPlaceholder> src,
accessor<DestT, DestDims, DestMode, DestTgt, IsDestPlaceholder>dest);
template <typename T, int Dims, access_mode Mode, target Tgt,

明示的なコピー

access::placeholder IsPlaceholder>

handler::require(acc) および
handler::update_host(acc) を含む

event update_host(accessor<T, Dims, Mode, Tgt, IsPlaceholder> acc);

コマンドグループの送信に相当します。

template <typename T, int Dims, access_mode Mode, target Tgt,

明示的なコピー

access: :placeholder IsPlaceholder>

handler::require(dest) および
handler::fill(dest, src) を含むコマン

event fill(accessor<T, Dims, Mode, Tgt, IsPlaceholder> dest, const T&

ドグループの送信に相当します。

src);

4.6.5.3. キュー情報記述子
キューでは、queue クラスの get_info メンバー関数を使用して、info::queue の info パラメーターで情報を照会できます。それぞれのinfo パラメーターに設定可能な値と制限は、キューに関連する SYCL バックエンドの仕様で定義されています。info::queue のすべての info パラメーターは表 30 に示し、info::queue の概要はA.4 節で説明します。
表 30. キュー情報記述子
キュー記述子

戻り値

説明

info::queue::context

context

SYCL queue に関連付けられている SYCL context を返します。

info::queue::device

deviceSYCL queue に関連付けられている SYCL デバイスを返します。

4.6.5.4. キュー・プロパティー
SYCL queue クラスを構築する際に提供できるプロパティーを表 31 に示します。
表 31. SYCL queue クラスでサポートされるプロパティー
プロパティー説明

property::queue::enable_profilingenable_profiling プロパティーは、関連する SYCL device がaspect::queue_profiling を持つ場合に、SYCL ランタイムがこの
SYCL queue から送信されたコマンドグループのプロファイル情報を取得して、SYCL event クラスの get_profiling_info メンバー
関数を使用して情報を取得する必要がある要件を追加します。

第 4 章 SYCL プログラミング・インターフェイス | 97

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

プロパティー説明

property::queue::in_order

in_order プロパティーは、SYCL queue がタスクに送信された順番で実行されるインオーダー・セマンティクスを提供する要件を追加します。この方法で送信されたタスクは、それ以前に送信された操作に暗黙的に依存すると見なすことができます。

queue property クラスのコンストラクターを表 32 に示します。
表 32. キュー・プロパティークラスのコンストラクター
コンストラクター

説明

property::queue::enable_profiling::enable_profiling()

SYCL enable_profiling プロパティーのインスタンスを作成します。

property::queue::in_order::in_order()SYCL in_order プロパティーのインスタンスを作成します。

4.6.5.5. キューエラー処理
キューエラーには次の 2 つの形式があります。

• 同期エラーは、イベントを待機する場所でキューが完了するのを待機し直接報告されることが想定されるエラーであり、ワークをキューに投入したときに報告される即時エラーです。このようなエラーは C++ 例外を介して報告されます。

• 非同期エラーは、関連するホスト API 呼び出しからリターンした後に生成または検出され (例外としてスローされることはありません)、エラーが報告される async_handler によって処理されるエラーです。4.13 節で説明されるように、キューからの非同期エ
ラーの処理は特定の時間で行われます。
キューが破棄された際に処理される非同期エラーがある場合ハンドラーが呼び出されますが、ハンドラーの動作に応じて破棄が遅延またはブロックされる可能性があることに注意してください。

4.6.6. イベントクラス
SYCL のイベントには、SYCL ランタイムで実行される操作の状態を示すオブジェクトが含まれます。
一般に、SYCL ではデータの依存関係と実行順序は、SYCL ランタイムによって暗黙的に処理されます。ただし、状況に応じて、開発者が実行を細かく制御したり、実行中のコマンドのプロパティーを取得することが必要な場合があります。
イベントは特定の操作の状態を表しますが、特定のイベントの依存関係を活用して、その操作を同期する際の複数のステップを追跡可能であることに注意してください。
SYCL イベントは、コマンドグループの送信によって返されます。コマンドグループの送信によって返されるイベントの依存関係は、コ
マンドグループの実行に関連付けられた実装定義のコマンドです。
SYCL event クラスは共通参照セマンティクスを提供します (4.5.2 節を参照)。
SYCL event クラスのコンストラクターとメンバー関数を表 33 と表 34 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、表 7 と表 8 を参照してください。

98 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス
1.

namespace sycl {2.
3.

class event {4.

public:5.

event();

6.
7.

/* -- 共通インターフェイスのメンバー -- */8.
9.

backend get_backend() const noexcept;

10.
11.

std::vector<event> get_wait_list();

12.
13.

void wait();

14.
15.

static void wait(const std::vector<event>& eventList);

16.
17.

void wait_and_throw();

18.
19.

static void wait_and_throw(const std::vector<event>& eventList);

20.
21.

template <typename Param> typename Param::return_type get_info() const;

22.
23.

template <typename Param>

24.

typename Param::return_type get_backend_info() const;

25.
26.

template <typename Param>

27.

typename Param::return_type get_profiling_info() const;

28.

};

29.
30.

} // namespace sycl

表 33. イベントクラスのコンストラクター
コンストラクター

説明event ()

直ちに準備できる event を作成します。event には依存関係や関連するコマンドはありません。この event を待機すると直ちにリターンし、ステータスを照会すると info::event_command_
status::complete が返されます。
イベントは、デフォルトで構築された queue から生成されたかのように構築されます。従って、そのバックエンドはデフォルトデバ
イスのバックエンドと同一です。

表 34. event クラスのメンバー関数
メンバー関数説明

backend get_backend() const noexcept

この event に関連付けられている SYCL バックエンドを識別する
backend を返します。

第 4 章 SYCL プログラミング・インターフェイス | 99

SYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

std::vector<event> get_wait_list()

このイベントが待機するイベントリストを依存関係グラフに返します。直接関連する依存関係のみが返され、そのような依存関係が待機する推移的ではない依存関係は返されません。すでに完了したイベントがイベントリストに含まれるかどうかは実装依存です。

void wait()

イベントとそれに関連するコマンドが完了するのを待機します。

void wait_and_throw()

イベントとそれに関連するコマンドが完了するのを待機します。
イベントが実行を待機するコンテキストからの非同期エラーである場合、コンテキストに関連付けられた async_handler に渡されます。ユーザー定義の async_handler がコンテキストに関連付
けられていない場合、4.13.1.2 節で説明されるように、実装定義のデフォルト async_handler が呼び出されてエラーが処理されます。

static void wait(

イベントリストを同期的に待機します。

const std::vector<event>& eventList)
static void wait_and_throw(
const std::vector<event>& eventList)

イベントリストを同期的に待機します。
イベントが実行を待機するコンテキストからの非同期エラーである場合、コンテキストに関連付けられた async_handler に渡されます。ユーザー定義の async_handler がコンテキストに関連付
けられていない場合、4.13.1.2 節で説明されるように、実装定義のデフォルト async_handler が呼び出されてエラーが処理されます。

template <typename Param>

テンプレート・パラメーター Param で要求される情報の SYCL

typename Param::return_type

event を照会します。タイプエイリアス Param::return_type は、

get_info() const

Param パラメーターに関連付けられたタイプを返すため、表 35の info パラメーターに従って定義する必要があります。

template <typename Param>

テンプレート・パラメーター Param が要求する SYCL バックエン

typename Param::return_type

ド固有の情報について SYCL event を照会します。タイプエイリ

get_backend_info() const

アス Param::return_type は、SYCL バックエンド仕様に従って定義する必要があります。Param に対応する SYCL バックエンド
が、event に関連付けられる SYCL バックエンドと異なる場合、
errc::backend_mismatch エラーコードで例外をスローする必要があります。

100 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.6 SYCL ランタイムクラス

メンバー関数説明

template <typename Param>

パラメーター Param で要求されるプロファイル情報の SYCL

typename Param::return_type

event を照会します。event に関連付けられたコマンドグループがget_profiling_info () const

完了する前に get_profiling_info が呼び出され、要求されたプロファイル情報が利用できない場合、get_profiling_info 呼び出しは要求されたプロファイル情報が利用可能になるまでブロックされます。例えば、関連するコマンドグループが実行を完了していない
場合に、info::event_profiling::command_end を要求することがあります。この SYCL event が関連付けられているコマンドグルー
プを送信した SYCL queue が property::queue::enable_profiling
プロパティーで構築されていない場合、get_profiling_info を呼び
出しは errc::invalid エラーコードで例外をスローする必要があります。タイプエイリアス Param::return_type は、Param パラメーターに関連付けられたタイプを返すため、表 37Table_36 の info パラ
メーターに従って定義する必要があります。

4.6.6.1. イベント情報とプロファイル記述子
イベントでは、event クラスの get_info メンバー関数を使用して、info::event の info パラメーターで情報を照会できます。それぞれの info パラメーターに設定可能な値と制限は、イベントに関連する SYCL バックエンドの仕様で定義されています。info::event のす
べての info パラメーターは表 35 に示し、info::event の概要は A.6 節で説明します。
表 35. イベントクラス情報記述子
イベント記述子

戻り値

説明

info::event::command_execution_status

info::event_comm

コマンドグループのイベント状態と、この SYCL event に関連

and_status

付けられたアクション (カーネル呼び出しなど) を返します。

info::event_command_status クエリーは、表 36 に定義されたいずれかの値を返します。
表 36. イベントコマンド状態
状態

説明

info::event_command_status::submitted

コマンドは SYCL queue に送信されましたが、デバイス上では実行が開始されていないことを示します。

info::event_command_status::running

コマンドはデバイスで実行を開始しましたが、まだ完了していないことを示します。

info::event_command_status::complete

コマンドはデバイスで実行を完了したことを示します。このイベントで待機するとブロックされることはありません。

第 4 章 SYCL プログラミング・インターフェイス | 101

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
イベントでは、event クラスの get_profiling_info メンバー関数を使用して、info::event_profiling に列挙されている info パラメーターの 1 つを指定して、プロファイル情報のイベントを照会できます。それぞれの info パラメーターに設定可能な値と制限は、イベントに関連する SYCL バックエ ンドの仕様で定義されています 。info::event_profiling のすべての info パラメーターは表 37 に示し、
info::event_profiling の概要は A.6 節で説明します。
それぞれのプロファイル記述子は、実装で定義されたタイムベースからのナノ秒単位の経過時間を示す 64 ビットのタイムスタンプを返します。同じバックエンドを共有するすべてのイベントは、同じタイムベースを共有することが保証されています。従って、同じバックエンドからの 2 つのタイムスタンプの差は、それらのイベント間で経過したナノ秒単位の数を生成します。
表 37. SYCL event クラスのプロファイル情報記述子
イベント情報プロファイル記述子

戻り値

説明

info::event_profiling::command_submit

uint64_t

関連するコマンドグループが queue に送信された時間をナノ秒単位で示す実装定義の 64 ビット値を返します。これは常に、コマンドグループ関数オブジェクトが戻った後、関連する
queue::submit の呼び出しが戻るまでの時間になります。

info::event_profiling::command_startuint64_t

このプロファイル記述子の照会は、イベント状態がinfo::event_command_status::running ま た は info::event_command_status::complete になるまでブロックされます。コマンドグループに関連付けられているアクション (カーネル呼び出
しなど) が、デバイスで実行を開始した時間を示すタイムスタンプを返します。任意のイベントで、このタイプスタンプは常に
info::event_profiling::command_submit 以上になります。実装
では、デバイスで実行開始された時点に近いタイムスタンプを返すことが推奨されますが、特定の精度が保証されるわけではありません。

info::event_profiling::command_end

uint64_t

このプロファイル記述子の照会は、イベント状態がinfo::event_command_status::complete になるまでブロッ
クされます。コマンドグループに関連付けられているアクション (カーネル呼び出しなど) が、デバイスで実行を完了した時間を示すタイムスタンプを返します。任意のイベントで、このタイ
プスタンプは常に info::event_profiling::command_start 以
上になります。

4.7. SYCL のデータアクセスとストレージ
SYCL でバッファーとイメージを使用する場合、データストレージとアクセスは別のクラスで処理されます。バッファーとイメージはデー
タストレージと所有権を処理しますが、アクセサーはデータへのアクセスを処理します。SYCL のバッファーとイメージは、異なる SYCL
バックエンド間を含め、複数のデバイスやコンテキストにバインドできます。また、データの所有権も処理して、ブロック化または非ブロック化のデータ転送の例外処理を可能にします。アクセサーは、ホストとシステム上のすべてのデバイス間のデータ転送、およびデータの依存関係を追跡して管理します。
サイズがゼロのバッファーが許可されます。この場合、バッファーは引き継ぎ通常どおりに所有権の処理を行いますが、ゼロサイズのデータをストアする必要はありません。

102 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
USM 割り当てを利用する場合、データストレージは USM 割り当て機能によって管理され、データはポインターを介してアクセスされます。詳細ついては 4.8 節をご覧ください。

4.7.1. ホスト割り当て
SYCL ランタイムは、一部の操作 (1 つのコンテキストから別のコンテキストへのデータコピーなど) を処理するため、ホスト上に一時的なオブジェクトを割り当てる必要があります。ホスト上の割り当ては、標準 C++ アロケーター・クラスの定義に従って、アロケーター・オ
ブジェクトを使用して管理されます。メモリー・オブジェクトのデフォルト・アロケーターは実装定義ですが、ユーザーが独自のアロケー
ター・クラスを用意することができます。
1.

{

2.
3.

buffer<int, 1, UserDefinedAllocator<int>> b(d);}アロケーターが nullptr を返す場合、ランタイムはホスト上にデータを割り当てることができません。その場合、ランタイムがホストメ
モリーを必要として、それが利用できない場合 (SYCL バックエンドのコンテキスト間でデータを移動するなど)、エラーを発生することに注意してください。
バッファーが破棄された後も、実装がアロケーター・オブジェクトのコピーを保持することがあります。例えば、バッファーへのアクセサーを使用するコマンドが完了する前に、バッファー・オブジェクトが破棄された場合などです。そのため、バッファーが破棄された後も、アプリケーションはアロケーターへの呼び出しに備えなければなりません。
実装がいつアロケーターのコピーをすべて破棄したかを知る必要がある場合、アプリケーションはアロケーター内の参照カウントを維持することができます。
アロケーターの定義は SYCL の機能を拡張して、ユーザーが特定のハードウェアや複雑な共有メモリーメカニズム (NUMA など) 向けのアロケーター機能を定義できるようにし、STL ベースのライブラリーとの相互運用性を向上させます (例: インテル® oneTBB のアロ
ケーターなど)。

4.7.1.1. デフォルト・アロケーター
デフォルトのアロケーターは常に実装定義であり、呼び出しごとに nullptr 以外の新しいメモリー位置が返されることを保証します。
const バッファーのデフォルト・アロケーターは、タイプの const 特性を排除します (つまり、const int タイプのバッファーのデフォルト・
アロケーターは、Allocator<int> になります)。これは、ホストアクセサーがバッファー/イメージ・コンストラクターでユーザーが指定するポインターと同期せず、Allocator 自身が返すメモリーを使用することを意味します。ユーザーは、バッファー・コンストラクターで渡されるのと同じアドレスを返すアロケーターを実装できますが、潜在的な競合状態を処理するのはユーザーの責任となります。
表 38. SYCL デフォルト・アロケーター
アロケーター

説明

template <class T> buffer_allocator

ユーザーがアロケーターを定義していない場合にランタイムが使用するデフォルトのバッファー・アロケーターです。C++ の名前
付き Allocator の要件を満たします。データタイプ const T のバッファーは、デフォルトで buffer_allocator<T> を使用します。

image_allocator

ユーザーがアロケーターを定義していない場合に、ランタイムがSYCL unsampled_image と sampled_image クラスで使用す第 4 章 SYCL プログラミング・インターフェイス | 103

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージる デ フ ォ ル ト の ア ロ ケ ー タ ー で す 。 image_allocator は 、
std::byte の要素に割り当てる必要があります。
ホストとデバイスの手動同期の詳細については、4.7.5 節を参照してください。

4.7.2. バッファー
buffer クラスは、SYCL カーネルで使用されるアクセサークラスを介してアクセスする必要がある 1 次元、2 次元、または 3 次元の共有配列を定義します。バッファーは、データタイプとデータが保存およびアクセスされる次元数でテンプレート化されます。
buffer は、ベースとなる単一のバックエンド・オブジェクトにのみマップされるわけではなく、すべての SYCL バックエンドのメモリー・
オブジェクトが特定のデバイスのコマンドグループで一時的に使用されることがあります。
バッファー T のベースとなるデータタイプは、3.13.1 節で定義されるようにデバイスでコピー可能である必要があります。buffer コン
ストラクターの一部のオーバーロードは、ホストメモリーからオブジェクトをコピーすることで初期化されますが、ほかのオーバーロー
ドは、ホストからオブジェクトをコピーすることなくバッファーを構築します。ホストのオブジェクトをコピーしないオーバーロードでは、
バッファー内のオブジェクトの初期化は、T が暗黙の持続時間タイプ (C++ コア言語で定義) であるかによって異なります。T が暗黙的な持続時間タイプである場合、そのタイプのオブジェクトには不定値のバッファーが暗黙的に作成されます。ほかのタイプでは、これらのコンストラクターのオーバーロードは初期化されていないメモリーを割り当てるのみであり、アプリケーションはプレースメント
new を呼び出してオブジェクトを構築し、オブジェクトのデストラクターを手動で呼び出して破棄する必要があります。
SYCL buffer は、メンバー関数 reinterpret を使用して、元の SYCL buffer とは異なるタイプ、次元、およびレンジで再解釈する SYCL
buffer のインスタンスを作成できます。再解釈によって構築された SYCL buffer は、再解釈された SYCL buffer タイプ、次元、およびレンジが、元のタイプと次元を反映する必要があることを除いて、reinterpret メンバー関数を呼び出したときに構築した SYCL bufferのコピーであるかのように動作する必要があります (4.5.2 節を参照)。これを拡張することで、クラス・メンバー・タイプ value_type、
reference、const_reference、および再解釈された SYCL buffer のメンバー関数 get_range() および size() は、新しいタイプ、次元、
そしてレンジを反映する必要があります。元の SYCL buffer と再解釈された SYCL buffer が管理するデータは影響を受けませんが、再解釈された SYCL buffer を介してアクセスされるデータは、新しいタイプ、次元、およびレンジを反映して変更されることがあります。
再解釈された SYCL buffer は、元の SYCL buffer のコピーであり、新しい SYCL buffer ではないことに注意してください。
同じホストポインターを管理する SYCL buffer を構築すると未定義の動作となります。
SYCL buffer クラスは共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.7.2.1. バッファー・インターフェイスSYCL buffer クラスのコンストラクターとメンバー関数を表 39 と表 40 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、表 7 と表 8 を参照してください。
各コンストラクターは、最後のパラメーターとしてオプションの SYCL property_list を受け取って、SYCL buffer にプロパティーを提供します。
SYCL buffer クラス・テンプレートは、ホスト上に一時メモリーを割り当てる際に SYCL ランタイムによって使用されるアロケーターを
指 定 す る テ ン プ レ ー ト ・ パ ラ メ ー タ ー AllocatorT を 受 け 取 り ま す 。 テ ン プ レ ー ト 引 数 が 省 略 さ れ ると 、 SYCL buffer クラ ス
buffer_allocator<T> のデフォルト・アロケーターが使用されます (4.7.1.1 節を参照)。
1.

namespace sycl {2.

namespace property {3.

namespace buffer {4.

class use_host_ptr {104 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
5.

public:6.
7.

use_host_ptr() = default;
};

8.
9.

class use_mutex {10.

public:11.

use_mutex(std::mutex& mutexRef);

12.
13.
14.

std::mutex* get_mutex_ptr() const;
};

15.
16.

class context_bound {17.

public:18.

context_bound(context boundContext);

19.
20.

context get_context() const;

21.

};

22.

} // namespace buffer23.

} // namespace property

24.
25.

template <typename T, int Dimensions = 1,

26.

typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>27.

class buffer {28.

public:29.

using value_type = T;30.

using reference = value_type&;

31.

using const_reference = const value_type&;

32.

using allocator_type = AllocatorT;

33.
34.

buffer(const range< Dimensions >& bufferRange,

35.

const property_list& propList = {});

36.
37.
38.

buffer(const range< Dimensions >& bufferRange, AllocatorT allocator,
const property_list& propList = {});

39.
40.
41.

buffer(T* hostData, const range< Dimensions >& bufferRange,
const property_list& propList = {});

42.
43.

buffer(T* hostData, const range< Dimensions >& bufferRange,

44.

AllocatorT allocator, const property_list& propList = {});

45.
46.
47.

buffer(const T* hostData, const range< Dimensions >& bufferRange,
const property_list& propList = {});

48.
49.

buffer(const T* hostData, const range< Dimensions >& bufferRange,

50.

AllocatorT allocator, const property_list& propList = {});

51.
52.

/* コンテナーが連続したコンテナーである場合にのみ利用できます:53.

- std::data(container) と std::size(container) は整形式です54.

- std::data(container) の戻り値は T* タイプに変換可能で、

55.

Dimensions == 1 です */56.

template <typename Container>

第 4 章 SYCL プログラミング・インターフェイス | 105

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ57.

buffer(Container& container, AllocatorT allocator,

58.

const property_list& propList = {});

59.
60.

/* コンテナーが連続したコンテナーである場合にのみ利用できます:61.

- std::data(container) と std::size(container) は整形式です62.

- std::data(container) の戻り値は T* タイプに変換可能で、

63.

Dimensions == 1 です */64.

template <typename Container>

65.

buffer(Container& container, const property_list& propList = {});

66.
67.

buffer(const std::shared_ptr<T>& hostData,

68.

const range<Dimensions>& bufferRange, AllocatorT allocator,

69.

const property_list& propList = {});

70.
71.

buffer(const std::shared_ptr<T>& hostData,

72.

const range<Dimensions>& bufferRange,

73.

const property_list& propList = {});

74.
75.

buffer(const std::shared_ptr<T[]>& hostData,

76.

const range<Dimensions>& bufferRange, AllocatorT allocator,

77.

const property_list& propList = {});

78.
79.

buffer(const std::shared_ptr<T[]>& hostData,

80.

const range<Dimensions>& bufferRange,

81.

const property_list& propList = {});

82.
83.

template <class InputIterator>

84.

buffer<T, 1>(InputIterator first, InputIterator last, AllocatorT allocator,

85.

const property_list& propList = {});

86.
87.

template <class InputIterator>

88.

buffer<T, 1>(InputIterator first, InputIterator last,

89.

const property_list& propList = {});

90.
91.

buffer(buffer& b, const id<Dimensions>& baseIndex,

92.

const range<Dimensions>& subRange);

93.
94.

/* -- 共通インターフェイスのメンバー -- */

95.
96.

/* -- プロパティー・インターフェイスのメンバー -- */

97.
98.

range<Dimensions> get_range() const;

99.
100.

size_t byte_size() const noexcept;

101.
102.

size_t size() const noexcept;

103.
104.

// 非推奨105.

size_t get_count() const;

106.
107.

// 非推奨108.

size_t get_size() const;

106 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
109.
110.

AllocatorT get_allocator() const;

111.
112.

template <access_mode Mode = access_mode::read_write, target Targ = target::device>

113.

accessor<T, Dimensions, Mode, Targ> get_access(114.

handler& commandGroupHandler);

115.
116.

// 非推奨117.

template <access_mode Mode>

118.

accessor<T, Dimensions, Mode, target::host_buffer> get_access();

119.
120.

template <access_mode Mode = access_mode::read_write, target Targ = target::device>

121.

accessor<T, Dimensions, Mode, Targ> get_access(122.

handler& commandGroupHandler, range<Dimensions> accessRange,

123.

id<Dimensions> accessOffset = {});

124.
125.

// 非推奨126.

template <access_mode Mode>

127.

accessor<T, Dimensions, Mode, target::host_buffer> get_access(128.

range<Dimensions> accessRange, id<Dimensions> accessOffset = {});

129.
130.

template<typename...Ts>

131.

auto get_access(Ts...);

132.
133.

template<typename...Ts>

134.

auto get_host_access(Ts...);

135.
136.

template <typename Destination = std::nullptr_t>

137.

void set_final_data(Destination finalData = nullptr);

138.
139.

void set_write_back(bool flag = true);

140.
141.

bool is_sub_buffer() const;

142.
143.

template <typename ReinterpretT, int ReinterpretDim>

144.

buffer<ReinterpretT, ReinterpretDim,

145.

typename std::allocator_traits<AllocatorT>::template rebind_alloc<

146.

ReinterpretT>>

147.

reinterpret(range<ReinterpretDim> reinterpretRange) const;

148.
149.

// ReinterpretDim == 1 または150.

// (ReinterpretDim == Dimensions) &&151.

// (sizeof(ReinterpretT) == sizeof(T)) のときにのみ利用できます。

152.

template <typename ReinterpretT, int ReinterpretDim = Dimensions>153.

buffer<ReinterpretT, ReinterpretDim,

154.

typename std::allocator_traits<AllocatorT>::template rebind_alloc<

155.

ReinterpretT>>

156.
157.

reinterpret() const;
};

158.
159.

// デダクション・ガイド

160.

template <class InputIterator, class AllocatorT>

第 4 章 SYCL プログラミング・インターフェイス | 107

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
161.
162.

buffer(InputIterator, InputIterator, AllocatorT, const property_list& = {})-> buffer<typename std::iterator_traits<InputIterator>::value_type, 1,

163.

AllocatorT>;

164.
165.

template <class InputIterator>

166.

buffer(InputIterator, InputIterator, const property_list& = {})167.

-> buffer<typename std::iterator_traits<InputIterator>::value_type, 1>;

168.
169.

template <class T, int Dimensions, class AllocatorT>

170.

buffer(const T*, const range<Dimensions>&, AllocatorT,

171.
172.

const property_list& = {})-> buffer<T, Dimensions, AllocatorT>;

173.
174.

template <class T, int Dimensions>175.

buffer(const T*, const range<Dimensions>&, const property_list& = {})176.

-> buffer<T, Dimensions>;

177.
178.

template <class Container, class AllocatorT>

179.

buffer(Container&, AllocatorT, const property_list& = {})180.

->buffer<typename Container::value_type, 1, AllocatorT>;

181.
182.

template <class Container>

183.

buffer(Container&, const property_list& = {})

184.
185.

->buffer<typename Container::value_type, 1>;} // namespace sycl

表 39. buffer クラスのコンストラクター
コンストラクター説明buffer(const range<Dimensions>& bufferRange,

初期化されていないメモリーを使用して SYCL buffer インスタン

const property_list& propList = {})スを作成します。作成された SYCL buffer は、ホストにメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します 。 構 築 さ れ た SYCL buffer の レ ン ジ は 、 与 え ら れ た
bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。 メ ン バ ー 関 数
set_final_data() を介して buffer に有効な非 NULL ポインターが指定されない限り、buffer を破棄する際にデータがホストに書き戻されることはありません。property_list のインスタンスを介して、構築された SYCL buffer に 0 個以上のプロパティーを供給できます。

108 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明buffer(const range<Dimensions>& bufferRange,

初期化されていないメモリーを使用して SYCL buffer インスタン

AllocatorT allocator,スを作成します。構築された SYCL buffer は、ホストにメモリーをconst property_list& propList = {})割り当てる際に提供される allocator パラメーターを使用します 。 構 築 さ れ た SYCL buffer の レ ン ジ は 、 与 え ら れ た
bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。 メ ン バ ー 関 数
set_final_data() を介して buffer に有効な非 NULL ポインターが指定されない限り、buffer を破棄する際にデータがホストに書き戻されることはありません。property_list のインスタンスを介して、構築された SYCL buffer に 0 個以上のプロパティーを供給できます。

buffer(T* hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。バッファーは hostData で指定されたメモ

const property_list& propList = {})リーで初期化されます。このメモリーの所有権は、そのライフタイ
ム中作成された SYCL buffer に与えられます。作成された SYCL
buffer は、ホストメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。構築される SYCL buffer のレン
ジは、bufferRange パラメーターで指定されます。property_listのインスタンスを介して、構築された SYCL buffer に 0 個以上のプロパティーを提供できます。

buffer(T* hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。バッファーは hostData で指定されたメモ

AllocatorT allocator,

リーで初期化されます。このメモリーの所有権は、そのライフタイ

const property_list& propList = {})ム中作成された SYCL buffer に与えられます。構築された SYCL
buffer は 、 ホ ス ト に メ モ リ ー を 割 り 当 て る 際 に 提 供 さ れ る
allocator パラメーターを使用します。構築される SYCL bufferの レ ン ジ は 、 bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 109

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明buffer(const T* hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。このメモリーの所有権はそのライフタイム

const property_list& propList = {})中作成された SYCL buffer に与えられます。
構築された SYCL buffer は、ホストにメモリーを割り当てると、デフォルトで構築された AllocatorT を使用します。
ホストアドレスは const T であるため、ホストアクセスは読み取り専用にできます。ただし、typename T は const でないため、デバイ
スアクセスは読み取りと書き込みアクセスの両方になります。
hostData は const であるため、このバッファーはこのメモリーのみを 初期 化で き、 buffer の構 築後 にメン バー 関数 set_final_data() で指定された有効な NULL 以外のデータアドレスが bufferにない限り、破棄された後にライトバックされることはありません。
構築された SYCL buffer のレンジは、bufferRange パラメーターで指定されます。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを提供できます。

buffer(const T* hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。このメモリーの所有権はそのライフタイム

AllocatorT allocator,
const property_list& propList = {})中作成された SYCL buffer に与えられます。
構築された SYCL buffer は、ホストにメモリーを割り当てる際に提供される allocator パラメーターを使用します。
ホストアドレスは const T であるため、ホストアクセスは読み取り専用にできます。ただし、typename T は const でないため、デバイ
スアクセスは読み取りと書き込みアクセスの両方になります。
hostData は const であるため、このバッファーはこのメモリーのみを 初期 化で き、 buffer の構 築後 にメン バー 関数 set_final_data() で指定された有効な NULL 以外のデータアドレスが bufferにない限り、破棄された後にライトバックされることはありません。
構築された SYCL buffer のレンジは、bufferRange パラメーターで指定されます。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを提供できます。

110 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename Container>

std::data(container) で始まり std::size(container) の要素数をbuffer(Container& container,

含む要素から、1 次元の SYCL buffer インスタンスを構築します。

const property_list& propList = {})バ ッ フ ァ ー は container の コ ン テ ン ツ で 初 期 化 さ れ 、 こ の
container の所有権はそのライフタイム中構築され た SYCL
buffer に与えられます。
std::data(container) の 戻 り 値 が const タ イ プ で な い 場 合 、
buffer の破棄が完了する前にデータは container にライトバッ
クされます。
構築された SYCL buffer は、ホストメモリーに割り当てられると、
デフォルトで構築された AllocatorT を使用します。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを提供できます。
このコンストラクターは、Dimensions == 1 でパラメーター化された buffer に対してのみ、および std::data(container) が T* に変換可能な場合にのみ定義されます。

template <typename Container>

std::data(container) で始まり std::size(container) の要素数をbuffer(Container& container,

含む要素から、1 次元の SYCL buffer インスタンスを構築します。

AllocatorT allocator,

バ ッ フ ァ ー は container の コ ン テ ン ツ で 初 期 化 さ れ 、 こ のconst property_list& propList = {})container の所有権はそのライフタイム中構築され た SYCL
buffer に与えられます。
std::data(container) の 戻 り 値 が const タ イ プ で な い 場 合 、
buffer の破棄が完了する前にデータは container にライトバッ
クされます。
構築された SYCL buffer は、ホストにメモリーを割り当てる際に提供される allocator パラメーターを使用します。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを提供できます。
このコンストラクターは、Dimensions == 1 でパラメーター化された buffer に対してのみ、および std::data(container) が T* に変換可能な場合にのみ定義されます。

buffer(const std::shared_ptr<T>& hostData,

提供された hostData パラメーターを使用して SYCL buffer イ

const range<Dimensions>& bufferRange,

ンスタンスを作成します。このメモリーの所有権はそのライフタ

const property_list& propList = {})イム中作成された SYCL buffer に与えられます。構築された
SYCL buffer は、ホストにメモリーを割り当てる際にデフォルトで 構 築 さ れ た AllocatorT を 使 用 し ま す 。 構 築さ れ た SYCL
buffer のレンジは、bufferRange パラメーターで指定されます。property_list のインスタンスを介して、構築された SYCL
buffer に 0 個以上のプロパティーを供給できます。

第 4 章 SYCL プログラミング・インターフェイス | 111

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明buffer(const std::shared_ptr<T>& hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。このメモリーの所有権はそのライフタイム

AllocatorT allocator,

中作成された SYCL buffer に与えられます。構築された SYCL

const property_list& propList = {})buffer は 、 ホ ス ト に メ モ リ ー を 割 り 当 て る 際 に 提 供 さ れ る
allocator パラメーターを使用します。構築された SYCL bufferの レ ン ジ は 、 bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを供給できます。

buffer(const std::shared_ptr<T[]>& hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。このメモリーの所有権はそのライフタイム

const property_list& propList = {})中作成された SYCL buffer に与えられます。構築された SYCL
buffer は、ホストにメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。構築された SYCL buffer のレン ジ は 、 bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを供給できます。

buffer(const std::shared_ptr<T[]>& hostData,

提供された hostData パラメーターを使用して SYCL buffer イン

const range<Dimensions>& bufferRange,

スタンスを作成します。このメモリーの所有権はそのライフタイム

AllocatorT allocator,

中作成された SYCL buffer に与えられます。構築された SYCL

const property_list& propList = {})buffer は 、 ホ ス ト に メ モ リ ー を 割 り 当 て る 際 に 提 供 さ れ る
allocator パラメーターを使用します。構築された SYCL bufferの レ ン ジ は 、 bufferRange パ ラ メ ー タ ー で 指 定 さ れ ま す 。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを供給できます。

template <typename InputIterator>

first から last までのレンジで指定された要素で初期化された新buffer(InputIterator first, InputIterator last,

規割り当ての 1D バッファーを作成します。データは実行中に中const property_list& propList = {})間メモリーにコピーされます。データは提供されている同一イテ
レーター・セットにはライトバックされません。ただし、メンバー関数 set_final_data() を使用して指定された有効な非 const イテ
レーターが buffer にある場合、データはそのイテレーターにコ
ピーされます。作成された SYCL buffer は、ホストにメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを供給できます。

112 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename InputIterator>

first から last までのレンジで指定された要素で初期化された新buffer(InputIterator first, InputIterator last,

規に割り当ての 1D バッファーを作成します。データは実行中にAllocatorT allocator = {},中間メモリーにコピーされます。データは提供されている同一イ

const property_list& propList = {})テレーター・セットにはライトバックされません。ただし、メンバー
関数 set_final_data() を使用して指定された有効な非 const イ
テレーターが buffer にある場合、データはそのイテレーターにコ
ピーされます。構築された SYCL buffer は、ホストにメモリーを割り当てる際に提供される allocator パラメーターを使用します。
property_list のインスタンスを介して、構築された SYCL bufferに 0 個以上のプロパティーを供給できます。

buffer(buffer& b, const id<Dimensions>& baseIndex,
const range<Dimensions>& subRange)

後で個別のアクセサーを定義するため、割り当てなしでサブバッファーを作成します。b は実際のデータを含むバッファーであり、サブバッファーであってはなりません。
baseIndex は、バッファー b 内のサブバッファーの始まりを指定します。subRange は、サブバッファーのサイズを指定します。任意の次元の baseIndex と subRange の合計は、その次元の親バッファー (b) サイズ (bufferRange) を超えることができず、違反した場合は errc::invalid エラーコードで例外をスローする必要があります。
baseIndex と subRange で指定されるオフセットとレンジは、元の SYCL buffer の連続した領域を示す必要があります。
サブバッファーを構築する際にバッファーの非連続領域が要求されると、errc::invalid エラーコードで例外をスローする必要があります。
構築されるサブバッファーの (baseIndex を基にした) 始まりは、
バッファーからデータにアクセスする SYCL device のメモリー・
ベース・アドレスの境界の倍数でなければなりません。この値は、
SYCL device クラスの情報クエリー info::device::mem_base_addr_align を介して取得できます。この要件に違反すると、実装は accessor コンストラクター (アクセサーがプレースホルダーでない場合)、または handler::require() (アクセサーがプレースホ
ルダーの場合) から errc::invalid エラーコードで例外をスローする必要があります。アクセサーがセカンダリー・キューを持つコマ
ンドグループにバインドされる場合、サブバッファーの配置はプライマリー・キュー・デバイスとセカンダリー・キュー・デバイスの両方と互換性を持つ必要があります。違反するとこの例外がスローされます。
b がサブバッファーである場合、errc::invalid エラーコードで例外
をスローする必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 113

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 40. buffer クラスのメンバー関数
メンバー関数説明

range<Dimensions> get_range() const

コンストラクターに渡される各次元の要素数から、バッファーサ
イズのレンジ・オブジェクトを返します。

size_t size() const noexcept

バッファーの合計要素数を返します。
get_range() [0] * ... * get_range()[Dimensions-1] と等価です。

size_t get_count() const

size() と同じ値を返します。非推奨です。

size_t byte_size() const noexcept

バッファー・ストレージのサイズをバイト単位で返します。
size()*sizeof(T) と等価です。

size_t get_size() const

byte_size() と同じ値を返します。非推奨です。

AllocatorT get_allocator() const

バッファーのアロケーターを返します。

template<access_mode Mode = access_mode::read_write,

コマンド・グループ・バッファー内の指定されたアクセスモードとtarget Targ = target::device>accessor<T, Dimensions, mode, Targ>
get_access(handler& commandGroupHandler)

ターゲットを持つバッファーへの accessor を返します。targetの値は、target::device または target::constant_buffer にできます。

template<access_mode Mode>SYCL 2020 では非推奨です。代わりに get_host_access() を使

accessor<T, Dimensions, mode, target::host_buffer>用します。

get_access()

指定されたアクセスモードとターゲットを持つバッファーへのaccessor を返します。

template<access_mode Mode = access_mode::read_write,target Targ=target::device>accessor<T, Dimensions, Mode, targ>
get_access(handler& commandGroupHandler,
range<Dimensions> accessRange,

コマンド・グループ・バッファー内の指定されたアクセスモードとターゲットを持つバッファーへの accessor を返します。レンジ付
きアクセサーである accessor を作成します。レンジはバッファーの 先 頭 か ら の オ フ セ ッ ト か ら 始 ま り ま す 。 target の 値 は 、target::device または target::constant_buffer にできます。

id<Dimensions> accessOffset = {})accessRange と accessOffset の 合 計 が い ず れ か の 次 元 でbuffer のレンジを超えると、errc::invalid エラーコードの例外を
スローします。
template<access_mode Mode>SYCL 2020 では非推奨です。代わりに get_host_access() を使

accessor<T, Dimensions, Mode, target::host_buffer>用します。

get_access(range<Dimensions> accessRange,
id<Dimensions> accessOffset = {})指定されたアクセスモードとターゲットを持つバッファーへのaccessor を返します。レンジ付きアクセサーである accessor を作成します。レンジはバッファーの先頭からのオフセットから始まります。target の値は target::host_buffer のみです。
accessRange と accessOffset の合計がいずれかの次元でバッ
ファーのレンジを超えると、errc::invalid エラーコードの例外をスローします。

114 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

template<typename...Ts>

バッファーと提供されたすべての引数を accessor コンストラク

auto get_access(Ts... args)

ターに渡して構築されたかように、有効な accessor を返します。
可能な実装:
return accessor{*this, args...};

template<typename...Ts>
auto get_host_access(Ts... args)

バッファーと提供されたすべての引数を host_accessor コンストラクターに渡して構築されたかように、有効な host_accessor を返します。
可能な実装:
return host_accessor{*this, args...};

template <typename Destination = std::nullptr_t>
void set_final_data(Destination finalData = nullptr)

finalData は、バッファーが書き込みアクセサーに関係づけられている場合、すべてのバッファー処理の結果が破棄時にコピーされる場所を示します。
デスティネーションは、出力イテレーターまたは std::weak_ptr<T>のどちらかです。
生ポインターは出力イテレーターの特殊ケースであり、結果のコ
ピー先であるホストメモリーを定義することに注意してください。
ウィークポインターである場合、ウィークポインターが期限切れであると出力は更新されません。
Destination が std::nullptr_t である場合、コピーバックは発生しません。

void set_write_back(bool flag = true)

このメンバー関数は、flag 値に応じて、破棄時にバッファーの
データのライトバックを強制、またはキャンセルできます。
ライトバックの強制は、4.7.2.3 節および 4.7.4 節で説明されている通常のライトバック中に発生するのと同じ効果を持ちます。
ライトバックする場所がない場合、この関数を使用しても効果がありません。

bool is_sub_buffer() const

SYCL buffer がサブバッファーである場合は true を返し、それ以外は false を返します。

第 4 章 SYCL プログラミング・インターフェイス | 115

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

template <typename ReinterpretT, int ReinterpretDim>

ReinterpretT で指定されたタイプ、ReinterpretDim で指定されbuffer<ReinterpretT, ReinterpretDim,
typename std::allocator_traits<AllocatorT>::template
rebind_alloc<ReinterpretT>>
reinterpret(range<ReinterpretDim> reinterpretRange)
const

た次元、reinterpretRange で指定されたレンジで再解釈された
SYCL buffer を作成して返します。再解釈されるバッファー・オブ
ジェクトは、SYCL buffer から作成された SYCL sub­buffer である可能性があるため、再解釈された SYCL buffer (または SYCL
sub-buffer) のタイプとレンジによって示されるバイト単位の合計サイズが、この SYCL buffer (または sub-buffer) のタイプとレンジのバイト単位の合計サイズと等しくない場合、errc::invalid
エラーコードの例外をスローする必要があります。サブバッファーを再解釈すると、再解釈されたサブバッファーのビューのみが提供され、親 buffer に対するサブバッファーのビューのオフセット
やサイズ (バイト単位) は変更されません。

template <typename ReinterpretT, int ReinterpretDim =ReinterpretT で指定されるタイプと ReinterpretDim で指定されDimensions>る次 元 で 、 再 解 釈 さ れ た SYCL buffer を 作 成 し て 返 し ま す 。

buffer<ReinterpretT, ReinterpretDim,
typename std::allocator_traits<AllocatorT>::template
rebind_alloc<ReinterpretT>>
reinterpret() const(ReinterpretDim == 1) または ((ReinterpretDim == Dimensions)&& (sizeof(ReinterpretT) == sizeof(T))) の場合にのみ有効です。再解釈されるバッファー・オブジェクトは、SYCL buffer から作成された SYCL sub­buffer である可能性があるため、再解釈された SYCL
buffer (または SYCL sub-buffer) のタイプとレンジによって示されるバイト単位の合計サイズが、sizeof (ReinterpretT) で均等に割り切れない場合、実装は errc::invalid エラーコードの例外をスローする必要があります。サブバッファーを再解釈すると、再解釈されたサ
ブバッファーのビューのみが提供され、親 buffer に対するサブバッ
ファーのビューのオフセットやサイズ (バイト単位) は変更されません。

4.7.2.2. バッファー・プロパティー
SYCL buffer クラスを構築する際に提供できるプロパティーを表 41Table_40 に示します。
表 41. SYCL buffer クラスでサポートされるプロパティー
プロパティー説明

property::buffer::use_host_ptr

use_host_ptr プロパティーは、SYCL ランタイムが SYCL bufferのメモリーを割り当てず、代わりに提供されるホストポインターを直接使用する要件を追加します。これにより、SYCL ランタイムがホストに一時ストレージを割り当てるのを防ぎます。
このプロパティーには、hostData ポインターから構築されるバッ
ファーに対して特別な保証があります。host_accessor がそのようなバッファーから構築されている場合、operator[](id<>) などのアクセサーのメンバー関数が返す reference タイプアドレスは対応する hostData アドレスと同一です。

116 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

property::buffer::use_mutex

use_mutex プロパティーは、SYCL buffer、unsampled_image
および sampled_image クラスで有効です。このプロパティーは、
SYCL buffer が所有するメモリーをプロパティーに提供されている std::mutex を介してアプリケーションと共有できる要件を追加します。ミューテックス m は、データが使用される際は常にロックされ、それ以外ではアンロックされます。ミューテックスがランタイムでロック解除されると、データは hostData と同期されます。

property::buffer::context_boundcontext_bound プロパティーは、SYCL buffer がプロパティーに提供される単一の SYCL context にだけ関連付けることが可能であるという要件を加えます。

buffer property クラスのコンストラクターとメンバー関数を表 42 と表 43 に示します。
表 42. buffer property クラスのコンストラクター
コンストラクター

説明

property::buffer::use_host_ptr::use_host_ptr()

SYCL use_host_ptr プロパティーのインスタンスを作成します。

property::buffer::use_mutex::use_mutex(std::mutex&指定された mutexRef パラメーターへの参照を使用して、SYCL

mutexRef)

use_mutex プロパティーのインスタンスを作成します。

property::buffer::context_bound::context_bound(context

SYCL context のコピーを使用して SYCL context_bound プロ

boundContext)

パティーのインスタンスを作成します。

表 43. buffer property クラスのメンバー関数
メンバー関数説明

std::mutex* property::buffer::use_mutex::get_mutex_ptr()

SYCL use_mutex プ ロ パ テ ィ ー を 作 成 す る 際 に 指 定 し た

const

std::mutex を返します。

context property::buffer::context_bound::get_context()

SYCL context_bound プロパティーを作成する際に指定した

constcontext を返します。

4.7.2.3. バッファー同期規則
バッファーは参照カウントされます。バッファー値がほかのバッファーから構築される場合、2 つの値は同じバッファーを参照して参照
カウントがインクリメントされます。バッファー値が破棄されると参照カウントがデクリメントされます。特定のバッファーを参照する
バッファー値がなくなると実際のバッファーが破棄され、以下に定義されるバッファーの破棄操作が実行されます。
バッファーの破棄時にエラーが発生すると、関連するキューの非同期エラー処理メカニズムを介して報告されます。
基本的にバッファー・デストラクターは、書き込みアクセサーが作成されたことでライトバックするデータがある場合、またはバッファーがホストメモリーで構築され使用中の場合にブロックします。

第 4 章 SYCL プログラミング・インターフェイス | 117

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
より厳密には:
1.

バッファーは range から (hostData ポインターなしで) 構築できます。このタイプのバッファーのメモリー管理は、SYCL シ
ステムによって処理されます。また、このタイプのバッファー・デストラクターは、バッファーのワークが完了していなくてもブロックする必要はありません。代わりに、SYCL システムはバッファーがキューで未使用状態となったときに、非同期にバッファーのストレージを解放します。バッファーの初期の内容は未定義です。

2.

バッファーは hostData ポインターから構築できます。バッファーは、存続期間中ホストメモリーを使用しますが、ホストメ
モリーの内容は未定義です。ホストメモリーがホストから変更されるか、またはバッファーの存続期間中に別のバッファーやイメージの構築に使用されると、結果は未定義となります。バッファーの初期の内容は構築時のホストメモリーの内容となります。
バッファーが破棄されると、デストラクターはバッファー上のキューのすべてのワークが完了するまでブロックし、必要に応じてバッファーの内容をホストメモリーにコピーバックしてリターンします。
a. ホストデータが const である場合、バッファーは read-only であり読み取り専用です。
バッファーは読み取りアクセスのみが許可され、ホストメモリーへのコピーバックは行われません (ただし、ホストメモ
リーは SYCL で利用できるように保持する必要があります)。デフォルトのバッファー・アロケーターを使用する場合、ホスト割り当てのメモリーを許容するため、タイプの const 特性は排除されます。これにより、ホストアクセスの高速化などのため、SYCL ランタイムによるデータの一時的なホストコピーが可能になります。
バッファーが破棄されると、デストラクターはバッファー上のキューのすべてのワークが完了するまでブロックしてからリターンします (ホストへコピーバックするデータがないため)。
b. ホストデータが const でなく、ホストデータへのポインターが const である場合、読み取り専用の制限はホストにのみ適用され、デバイスアクセスには適用されません。
バッファーが破棄されると、デストラクターはバッファー上のキューのすべてのワークが完了するまでブロックします。

3.

shared_ptr を使用してホストデータへのバッファーを構築できます。このポインターは、SYCL アプリケーションとランタイム間で共有されます。アプリケーションとランタイム間の同期には mutex が使用されます。ミューテックスは、データの使用中は常にランタイムによってロックされ不要になるとアンロックされます。
shared_ptr 参照カウントは、バッファーのホストデータが早期に破棄されるのを回避するために使用されます。バッファーが破棄される前に shared_ptr がアプリケーションで削除されても、ポインターは破棄されていないためバッファーはそのまま利用できます。ただし、アプリケーションがすでにコピーを削除しているため、破棄する前にデータがホストへコピー
バックされることはありません。
std::unique_ptr から std::shared_ptr への暗黙の変換があるため、std::unique_ptr を使用して所有権を SYCL ランタイ
ムに渡すことが可能であることを忘れないでください。

4.

バッファーはイテレーター値のペアから構築できます。この場合、バッファー構造は、イテレーターのペアによって定義されたデータレンジからデータをコピーします。デストラクターはデータをコピーバックせず、ブロックする必要もありません。

5.

バッファーは、std::data(container) と std::size(container) が整形式であるコンテナーから構築できます。バッファーの初期の内容は構築時のコンテナーの内容となります。
バッファーは、コンテナー内のメモリーを存続期間中使用することがあり、その間メモリーの内容は未定義です。このバッファーの存続期間中にコンテナーのメモリーがホストで変更されると、結果は未定義となります。
バッファーが破棄されると、デストラクターはバッファー上のキューのすべてのワークが完了するまでブロックします。
std::data(container) の戻り型が const でない場合、デストラクターは必要に応じてバッファーの内容をコンテナーにコピーします。

118 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
set_final_data() を使用してデータを書き戻す場所を変更すると、バッファーのデストラクターは書き込みアクセサーがある場合ブロックします。
ベースとなるバッファーの sub-range を参照する sub-buffer オブジェクトを作成できます。この sub-buffer は、sub-buffer の構築時に指定されたレンジにアクセスできるベースバッファーへのアクセサーを作成する際に使用されます。sub-buffer は、sub-buffer から作成することはできません。ｓub-buffer ではないベースバッファーからのみ作成できます。
ｓub-buffer は、バッファーの連続したメモリー領域から構築する必要があります。この要件は、次元が 1 次元より大きなバッファーを操作する場合分かりにくいかもしれませんが、インデックス・マッピングの計算によるパフォーマンス・コストなしで、1 次元の SYCL
バックエンドのネイティブ割り当てに関連付けられます。
次に例を示します。
1.

buffer<int,2> parent_buffer { range<2>{ 8,8 } }; // 8 x 8 の整数で 2D バッファーを作成

2.
3.

// OK: バッファーの中央から連続した領域

4.

buffer<int,2> sub_buf1 { parent_buffer, /* オフセット */5.

range<2>{ 2,0 }, /* サイズ */6.

range<2>{2,8} };

7.
8.

// 不正な例外: 2D バッファーの連続しない領域

9.

buffer<int,2> sub_buf2 { parent_buffer, /* オフセット */10.

range<2>{ 2,0 }, /* サイズ */11.

range<2>{12.

2,2} };

buffer<int,2> sub_buf3 { parent_buffer, /* オフセット */13.

range<2>{ 2,2 }, /* サイズ */14.

range<2>{2,6} };

15.
16.

// 不正な例外: 範囲外のサイズ

17.

buffer<int,2> sub_buf4 { parent_buffer, /* オフセット */18.

range<2>{ 2,2 }, /* サイズ */19.

range<2>{2,8} };

4.7.3. イメージ
unsampled_image (表 44) と sampled_image (表 45) クラスは、1、2、または 3 次元の共有イメージを定義します。これらのデータ
は、キュー内のカーネルで使用でき、イメージ・アクセサー・クラスを介してアクセスする必要があります。
SYCL unsampled_image および sampled_image クラス・テンプレートのコンストラクターとメンバー関数を表 44、表 45、表 46 そして表 47 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、表 7 と表 8 を参照してください。
関連性がある場合、データ形式が image_format で記述された形式と一致していることを確認するのはユーザーの責任です。
SYCL unsampled_image および sampled_image クラスのアロケーター・テンプレート・パラメーターは、カスタム・アロケーターを含む任意のアロケーター・タイプにすることができますが、std::byte 単位で割り当てる必要があります。
range (r1, r2, r3) で構成され、要素タイプのサイズが s バイトであるイメージでは、イメージの行のピッチとスライスのピッチは次のよ
うに計算します。

第 4 章 SYCL プログラミング・インターフェイス | 119

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
SYCL unsampled_image および sampled_image クラス・テンプレートは、共通参照セマンティクスを提供します (4.5.2 節を参照)。

4.7.3.1. 非サンプル・イメージ・インターフェイス
unsampled_image の各コンストラクターは、image_format を使用してイメージデータのデータ配置を記述します。
各コンストラクターはさらに、最後のパラメーターとしてオプションの SYCL property_list を受け取って、SYCL unsampled_imageにプロパティーを提供します。
SYCL unsampled_image クラス・テンプレートは、ホスト上に一時メモリーを割り当てる際に SYCL ランタイムによって使用されるアロ ケ ー タ ー を 指 定 す る テ ン プ レ ー ト ・ パ ラ メ ー タ ー AllocatorT を 受 け 取 り ま す 。 テ ン プ レ ー ト 引 数 が 省 略 さ れ る と 、 SYCL
unsampled_image クラスの image_allocator デフォルト・アロケーターが使用されます (4.7.1.1 節を参照)。
1.

namespace sycl {2.
3.

enum class image_format : /* 未定義 */ {4.

r8g8b8a8_unorm,

5.

r16g16b16a16_unorm,

6.

r8g8b8a8_sint,

7.

r16g16b16a16_sint,8.

r32b32g32a32_sint,

9.

r8g8b8a8_uint,

10.

r16g16b16a16_uint,11.

r32b32g32a32_uint,

12.

r16b16g16a16_sfloat,13.

r32g32b32a32_sfloat,

14.
15.

b8g8r8a8_unorm
};

16.
17.

template <int Dimensions = 1, typename AllocatorT = sycl::image_allocator>

18.

class unsampled_image {

19.
20.
21.

public:unsampled_image(image_format format, const range<Dimensions>& rangeRef,
const property_list& propList = {});

22.
23.
24.

unsampled_image(image_format format, const range<Dimensions>& rangeRef,
AllocatorT allocator, const property_list& propList = {});

25.
26.

/* Dimensions > 1 の場合にのみ利用できます。*/

27.

unsampled_image(image_format format, const range<Dimensions>& rangeRef,28.

const range<Dimensions -1>& pitch,

29.

const property_list& propList = {});

30.
31.

/* Dimensions > 1 の場合にのみ利用できます。*/

32.

unsampled_image(image_format format, const range<Dimensions>& rangeRef,

33.

const range<Dimensions -1>& pitch, AllocatorT allocator,

34.

const property_list& propList = {});

35.
36.

unsampled_image(void* hostPointer, image_format format,

37.

const range<Dimensions>& rangeRef,

38.

const property_list& propList = {});

39.

120 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
40.

unsampled_image(void* hostPointer, image_format format,

41.

const range<Dimensions>& rangeRef, AllocatorT allocator,

42.

const property_list& propList = {});

43.
44.

/* Dimensions > 1 の場合にのみ利用できます。*/

45.

unsampled_image(void* hostPointer, image_format format,

46.

const range<Dimensions>& rangeRef,

47.

const range<Dimensions -1>& pitch,48.

const property_list& propList = {});

49.
50.

/* Dimensions > 1 の場合にのみ利用できます。*/

51.

unsampled_image(void* hostPointer, image_format format,

52.

const range<Dimensions>& rangeRef,

53.

const range<Dimensions -1>& pitch, AllocatorT allocator,

54.

const property_list& propList = {});

55.
56.

unsampled_image(std::shared_ptr<void>& hostPointer, image_format format,

57.

const range<Dimensions>& rangeRef,58.

const property_list& propList = {});

59.
60.

unsampled_image(std::shared_ptr<void>& hostPointer, image_format format,

61.

const range<Dimensions>& rangeRef, AllocatorT allocator,

62.

const property_list& propList = {});

63.
64.

/* Dimensions > 1 の場合にのみ利用できます。*/

65.

unsampled_image(std::shared_ptr<void>& hostPointer, image_format format,

66.

const range<Dimensions>& rangeRef,67.

const range<Dimensions -1>& pitch,

68.

const property_list& propList = {});

69.
70.

/* Dimensions > 1 の場合にのみ利用できます。*/

71.

unsampled_image(std::shared_ptr<void>& hostPointer, image_format format,

72.

const range<Dimensions>& rangeRef,73.

const range<Dimensions -1>& pitch, AllocatorT allocator,

74.

const property_list& propList = {});

75.
76.

/* -- 共通インターフェイスのメンバー -- */

77.
78.

/* -- プロパティー・インターフェイスのメンバー -- */

79.
80.

range<Dimensions> get_range() const;

81.
82.

/* Dimensions > 1 の場合にのみ利用できます。*/

83.

range<Dimensions - 1> get_pitch() const;

84.
85.

size_t byte_size() const noexcept;

86.
87.

size_t size() const noexcept;

88.
89.

AllocatorT get_allocator() const;

90.
91.

template<typename...Ts>

第 4 章 SYCL プログラミング・インターフェイス | 121

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ92.

auto get_access(Ts... args);

93.
94.

template<typename...Ts>

95.

auto get_host_access(Ts... args);

96.
97.

template <typename Destination = std::nullptr_t>

98.

void set_final_data(Destination finalData = std::nullptr);

99.
100.
101.

ｖoid set_write_back(bool flag = true);
};

102.
103.

} // namespace sycl

表 44. unsampled_image クラス・テンプレートのコンストラクター
コンストラクター説明

unsampled_image(image_format format,

初期化されていないメモリーで SYCL unsampled_image イン

const range<Dimensions>& rangeRef,

スタンスを作成します。構築された SYCL unsampled_image

const property_list& propList = {})は、ホストにメモリーを割り当てる際にデフォルトで構築された
AllocatorT を使用します。構築された SYCL unsampled_imageの要素サイズは、format パラメーターから派生します。構築された SYCL unsampled_image のレンジは、rangeRef パラメー
ターから提供されます。構築された SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数 set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、破棄する際にライトバックされません。property_list のインスタンスを介して、構築された
SYCL unsampled_image に 0 個以上のプロパティーを提供できます。

unsampled_image(image_format format,

初期化されていないメモリーで SYCL unsampled_image イン

const range<Dimensions>& rangeRef,

スタンスを作成します。構築された SYCL unsampled_image

AllocatorT allocator,

は、ホストにメモリーを割り当てる際に提供される allocator パラ

const property_list& propList = {})メーターを使用します。構築された SYCL unsampled_image の要素サイズは、format パラメーターから派生します。構築された
SYCL unsampled_image のレンジは、rangeRef パラメーター
から提供されます。構築された SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数 set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、破棄する際にライトバックされません。property_list のインスタンスを介して、構築された SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

122 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明

unsampled_image(image_format format,

Dimensions > 1 の場合にのみ利用できます。

const range<Dimensions>& rangeRef,
const range<Dimensions-1>& pitch,
const property_list& propList = {})初期化されていないメモリーで SYCL unsampled_image イン
スタンスを作成します。構築された SYCL unsampled_image
は、ホストにメモリーを割り当てる際にデフォルトで構築された
AllocatorT を使用します。構築された SYCL unsampled_imageの要素サイズは、format パラメーターから派生します。構築された SYCL unsampled_image のレンジは、rangeRef パラメー
ターから提供されます。構築された SYCL unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数
set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、破棄する際にライトバックされません。property_listのインスタンスを介して、構築された SYCL unsampled_imageに 0 個以上のプロパティーを提供できます。

unsampled_image(image_format format,
const range<Dimensions>& rangeRef,
const range<Dimensions-1>& pitch,
AllocatorT allocator,
const property_list& propList = {})Dimensions > 1 の場合にのみ利用できます。
初期化されていないメモリーで SYCL unsampled_image イン
スタンスを作成します。構築された SYCL unsampled_image
は、ホストにメモリーを割り当てる際にデフォルトで構築された
allocator パ ラ メ ー タ ー を 使 用 し ま す 。 構 築 さ れ た SYCL
unsampled_image の要素サイズは、format パラメーターから派生します。構築された SYCL unsampled_image のレンジは、
rangeRef パラメーターから提供されます。 構築された SYCL
unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数 set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、破棄する際にライトバックされません。property_list のインスタンスを介して、構築された SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

unsampled_image(void* hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイ

const range<Dimensions>& rangeRef,

ム中に構築された SYCL unsampled_image に与えられます。構const property_list& propList = {})築された SYCL unsampled_image は、ホストメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。構築
された SYCL unsampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL unsampled_imageのレンジは、rangeRef パラメーターから提供されます。構築された SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数
set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたメモリーはすべて
hostPointer に書き戻されます。property_list のインスタンスを介して、構築された SYCL unsampled_image に 0 個以上のプ
ロパティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 123

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明

unsampled_image(void* hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイム

const range<Dimensions>& rangeRef,

中に構築された SYCL unsampled_image に与えられます。構築

AllocatorT allocator,

された SYCL unsampled_image は、ホストにメモリーを割り当て

const property_list& propList = {})る際に提供される allocator パラメーターを使用します。構築された SYCL unsampled_image の要素サイズは format パラメー
ターから派生します。構築された SYCL unsampled_image のレ
ンジは、rangeRef パラメーターから提供されます。構築された
SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数
set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたポインターはすべて
hostPointer に書き戻されます。property_list のインスタンスを介して、構築された SYCL unsampled_image に 0 個以上のプロ
パティーを提供できます。

unsampled_image(void* hostPointer,
image_format format,
const range<Dimensions>& rangeRef,
const range<Dimensions-1>& pitch,
const property_list& propList = {})Dimensions > 1 の場合にのみ利用できます。
hostPointer パラメーターを使用して SYCL unsampled_image
インスタンスを作成します。このメモリーの所有権は、ライフタイ
ム中に構築された SYCL unsampled_image に与えられます。構
築された SYCL unsampled_image は、ホストメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。構築
された SYCL unsampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL unsampled_imageのレンジは、rangeRef パラメーターから提供されます。構築された SYCL unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数 set_final_data() が有効な NULL
以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたメモリーはすべて hostPointer に書き戻れます。
property_list の イ ン ス タ ン ス を 介 し て 、 構 築 さ れ た SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

124 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明

unsampled_image(void* hostPointer,

Dimensions > 1 の場合にのみ利用できます。

image_format format,
const range<Dimensions>& rangeRef,
const range<Dimensions-1>& pitch,
AllocatorT allocator,
const property_list& propList = {})hostPointer パラメーターを使用して SYCL unsampled_image
インスタンスを作成します。このメモリーの所有権は、ライフタイム
中に構築された SYCL unsampled_image に与えられます。構築
された SYCL unsampled_image は、ホストにメモリーを割り当てる際に提供される allocator パラメーターを使用します。構築された SYCL unsampled_image の要素サイズは format パラメー
ターから派生します。構築された SYCL unsampled_image のレ
ンジは、rangeRef パラメーターから提供されます。構築された
SYCL unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数 set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てら れ た メ モ リ ー は す べ て hostPointer に 書 き 戻 れ ま す 。
property_list の イ ン ス タ ン ス を 介 し て 、 構 築 さ れ た SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

unsampled_image(std::shared_ptr<void>& hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイ

const range<Dimensions>& rangeRef,

ム中に構築された SYCL unsampled_image に与えられます。構const property_list& propList = {})築された SYCL unsampled_image は、ホストメモリーを割り当てる際にデフォルトで構築された AllocatorT を使用します。構築
された SYCL unsampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL unsampled_imageのレンジは、rangeRef パラメーターから提供されます。構築された SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数
set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたメモリーはすべて
hostPointer に書き戻されます。property_list のインスタンスを介して、構築された SYCL unsampled_image に 0 個以上のプ
ロパティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 125

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター説明

unsampled_image(std::shared_ptr<void>& hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイム

const range<Dimensions>& rangeRef,

中に構築された SYCL unsampled_image に与えられます。構築

AllocatorT allocator,

された SYCL unsampled_image は、ホストにメモリーを割り当て

const property_list& propList = {})る際に提供される allocator パラメーターを使用します。構築された SYCL unsampled_image の要素サイズは format パラメー
ターから派生します。構築された SYCL unsampled_image のレ
ンジは、rangeRef パラメーターから提供されます。構築された
SYCL unsampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。メンバー関数
set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたメモリーはすべて
hostPointer に書き戻されます。property_list のインスタンスを介して、構築された SYCL unsampled_image に 0 個以上のプロ
パティーを提供できます。

unsampled_image(std::shared_ptr<void>& hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイ

const range<Dimensions>& rangeRef,

ム中に構築された SYCL unsampled_image に与えられます。構const range<Dimensions-1>& pitch,

築された SYCL unsampled_image は、ホストメモリーを割り当

const property_list& propList = {})てる際にデフォルトで構築された AllocatorT を使用します。構築
された SYCL unsampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL unsampled_imageのレンジは、rangeRef パラメーターから提供されます。構築された SYCL unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数 set_final_data() が有効な NULL
以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てられたメモリーはすべて hostPointer に書き戻れます。
property_list の イ ン ス タ ン ス を 介 し て 、 構 築 さ れ た SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

unsampled_image(std::shared_ptr<void>& hostPointer,

hostPointer パラメーターを使用して SYCL unsampled_image

image_format format,

インスタンスを作成します。このメモリーの所有権は、ライフタイム

const range<Dimensions>& rangeRef,

中に構築された SYCL unsampled_image に与えられます。構築

const range<Dimensions-1>& pitch,

された SYCL unsampled_image は、ホストにメモリーを割り当て

AllocatorT allocator,

る際に提供される allocator パラメーターを使用します。構築されconst property_list& propList = {})た SYCL unsampled_image の要素サイズは format パラメー
ターから派生します。構築された SYCL unsampled_image のレ
ンジは、rangeRef パラメーターから提供されます。構築された
SYCL unsampled_image のピッチは、pitch パラメーターから提供されます。メンバー関数 set_final_data() が有効な NULL 以外のポインターで呼び出されない限り、SYCL ランタイムで割り当てら れ た メ モ リ ー は す べ て hostPointer に 書 き 戻 れ ま す 。
property_list の イ ン ス タ ン ス を 介 し て 、 構 築 さ れ た SYCL
unsampled_image に 0 個以上のプロパティーを提供できます。

126 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 45. unsampled_image クラス・テンプレートのメンバー関数
メンバー関数説明

range<Dimensions> get_range() const

コンストラクターに渡される各次元の要素数から、イメージサイ
ズのレンジ・オブジェクトを返します。

range<Dimensions-1> get_pitch() const

Dimensions > 1 の場合にのみ利用できます。
イメージのピッチをバイト単位で表すレンジ・オブジェクトを返します。

size_t size() const noexcept

イメージの合計要素数を返します。
get_range()[0] * ... * get_range()[Dimensions-1] と等価です。

size_t byte_size() const noexcept

イメージストレージのサイズをバイト単位で返します。効率良くアクセスするため、イメージ要素、行、スライスがパディングされるため、バイト数は size() * 要素サイズ よりも大きくなる可能性があります。

AllocatorT get_allocator() const

イメージのアロケーターを返します。

template<typename...Ts>イ メ ー ジ と 提 供 さ れ た す べ て の 引 数 を unsampled_image_auto get_access(Ts... args)

accessor コンストラクターに渡して構築されたかように、有効なunsampled_image_accessor を返します。
可能な実装:
return unsampled_image_accessor {*this, args...};

template<typename...Ts>
auto get_host_access(Ts... args)

イメージと提供されたすべての引数を host_unsampled_image_accessor コンストラクターに渡して構築されたかように、有効な
host_unsampled_image_accessor を返します。
可能な実装:
return host_unsampled_image_accessor {*this, args...};

template <typename Destination = std::nullptr_t>
void set_final_data(Destination finalData = nullptr)

finalData は、イメージが書き込みアクセサーに関係付けられている場合、すべてのイメージ処理の出力が破棄されるときにコピーされる場所を示します。
デスティネーションは、出力イテレーター、std::weak_ptr<T> のどちらかです。
生ポインターは出力イテレーターの特殊ケースであり、結果のコ
ピー先であるホストメモリーを定義することに注意してください。
ウィークポインターである場合、ウィークポインターが期限切れであると出力はコピーされません。
Destination が std::nullptr_t である場合、コピーバックは発生しません。

第 4 章 SYCL プログラミング・インターフェイス | 127

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

void set_write_back(bool flag = true)

このメンバー関数は、flag 値に応じて、破棄時にイメージデータのライトバックを強制、またはキャンセルできます。
ライトバックの強制は、4.7.3.4 節および 4.7.4 節で説明されている通常のライトバック中に発生するのと同じ効果を持ちます。
ライトバックする場所がない場合、この関数を使用しても効果がありません。

4.7.3.2. サンプル・イメージ・インターフェイス
sampled_image クラスの各コンストラクターには、イメージがサンプリングするホストデータへのポインター、データ配置を記述する
image_format、およびイメージデータのサンプリング方法を記述する image_sampler (4.7.8 節を参照) が必要です。
各コンストラクターは、最後のパラメーターとしてオプションの SYCL property_list を受け取って、SYCL sampled_image にプロパティーを提供します。
1.

namespace sycl {2.
3.

enum class image_format : /* 未定義 */ {4.

r8g8b8a8_unorm,

5.

r16g16b16a16_unorm,

6.

r8g8b8a8_sint,

7.

r16g16b16a16_sint,8.

r32b32g32a32_sint,

9.

r8g8b8a8_uint,

10.

r16g16b16a16_uint,11.

r32b32g32a32_uint,

12.

r16b16g16a16_sfloat,13.

r32g32b32a32_sfloat,

14.
15.

b8g8r8a8_unorm
};

16.
17.

template <int Dimensions = 1, typename AllocatorT = sycl::image_allocator>

18.

class sampled_image {

19.
20.

public:sampled_image(const void* hostPointer, image_format format,

21.

image_sampler sampler, const range<Dimensions>& rangeRef,22.

const property_list& propList = {});

23.
24.

/* Dimensions > 1 の場合にのみ利用できます。 */25.

sampled_image(const void* hostPointer, image_format format,

26.

image_sampler sampler, const range<Dimensions>& rangeRef,27.

const range<Dimensions -1>& pitch,

28.

const property_list& propList = {});

29.
30.
31.
32.

sampled_image(std::shared_ptr<const void>& hostPointer, image_format format,
image_sampler sampler, const range<Dimensions>& rangeRef,
const property_list& propList = {});

128 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
33.
34.

/* Dimensions > 1 の場合にのみ利用できます。 */35.

sampled_image(std::shared_ptr<const void>& hostPointer, image_format format,

36.

image_sampler sampler, const range<Dimensions>& rangeRef,

37.

const range<Dimensions -1>& pitch,

38.

const property_list& propList = {});

39.
40.

/* -- 共通インターフェイスのメンバー -- */

41.
42.

/* -- プロパティー・インターフェイスのメンバー -- */

43.
44.

range<Dimensions> get_range() const;

45.
46.

/* Dimensions > 1 の場合にのみ利用できます。 */47.

range<Dimensions - 1> get_pitch() const;

48.
49.

size_t byte_size() const;

50.
51.

size_t size() const;

52.
53.

template<typename...Ts>

54.

auto get_access(Ts... args);

55.
56.

template<typename...Ts>

57.

auto get_host_access(Ts... args);

58.

};

59.
60.

} // namespace sycl

表 46. sampled_image クラス・テンプレートのコンストラクター
コンストラクター

説明sampled_image(const void* hostPointer,

hostPointer パラメーターを使用して SYCL sampled_image イ

image_format format,

ンスタンスを作成します。このメモリーの所有権は、ライフタイム

image_sampler sampler,

中に構築された SYCL sampled_image に与えられます。ホスト

const range<Dimensions>& rangeRef,

アドレスは const であるため、ホストアクセスは読み取り専用でconst property_list& propList = {})す。hostPointer は const であるため、このイメージはこのメモ
リーでのみ初期化され、破棄されてもライトバックされません。構
築された SYCL sampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL sampled_image を読み取るアクセサーは、sampler パラメーターを使用してイメー
ジをサンプルします。構築された SYCL sampled_image のレン
ジは rangeRef パラメーター から提供されます。 構築された
SYCL sampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。property_list のインスタンスを介して、構築された SYCL sampled_image に 0 個以上のプロパティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 129

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明sampled_image(const void* hostPointer,

Dimensions > 1 の場合にのみ利用できます。

image_format format,
image_sampler sampler,
const range<Dimensions>& rangeRef,
const range<Dimensions-1>& pitch,
const property_list& propList = {})hostPointer パラメーターを使用して SYCL sampled_image イ
ンスタンスを作成します。このメモリーの所有権は、ライフタイム
中に構築された SYCL sampled_image に与えられます。ホスト
アドレスは const であるため、ホストアクセスは読み取り専用です。hostPointer は const であるため、このイメージはこのメモ
リーでのみ初期化され、破棄されてもライトバックされません。構
築された SYCL sampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL sampled_image を読み取るアクセサーは、sampler パラメーターを使用してイメー
ジをサンプルします。構築された SYCL sampled_image のレン
ジは rangeRef パラメーター から提供されます。 構築された
SYCL sampled_image のピッチは、pitch パラメーターから提供されます。構築された

SYCL sampled_image に は 、property_list のインスタンスを介して 0 個以上のプロパティーを提供できます。
sampled_image(std::shared_ptr<const void>&

hostPointer パラメーターを使用して SYCL sampled_image イ

hostPointer, image_format format,

ンスタンスを作成します。このメモリーの所有権は、ライフタイム

image_sampler sampler,

中に構築された SYCL sampled_image に与えられます。ホストア

const range<>& rangeRef,

ドレスは const であるため、ホストアクセスは読み取り専用です。

const property_list& propList = {})hostPointer は const であるため、このイメージはこのメモリーでのみ初期化され、破棄されてもライトバックされません。構築された SYCL sampled_image の要素サイズは format パラメーターから派生します。構築された SYCL sampled_image を読み取るアクセサーは、sampler パラメーターを使用してイメージをサンプ
ル し ま す 。 構 築 さ れ た SYCL sampled_image の レ ン ジ は
rangeRef パラメーターから提供されます。構築された SYCL
sampled_image のピッチは、SYCL ランタイムによって決定されるデフォルトサイズになります。構築された

SYCL

sampled_image には、property_list のインスタンスを介して 0個以上のプロパティーを提供できます。

130 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明sampled_image(std::shared_ptr<const void>&

hostPointer パラメーターを使用して SYCL sampled_image イ

hostPointer, image_format format,

ンスタンスを作成します。このメモリーの所有権は、ライフタイム

image_sampler sampler,

中に構築された SYCL sampled_image に与えられます。ホスト

const range<Dimensions>& rangeRef,

アドレスは const であるため、ホストアクセスは読み取り専用でconst range<Dimensions-1>& pitch,す。hostPointer は const であるため、このイメージはこのメモ

const property_list& propList = {})リーでのみ初期化され、破棄されてもライトバックされません。構
築された SYCL sampled_image の要素サイズは format パラ
メーターから派生します。構築された SYCL sampled_image を読み取るアクセサーは、sampler パラメーターを使用してイメー
ジをサンプルします。構築された SYCL sampled_image のレン
ジは rangeRef パラメーター から提供されます。 構築された
SYCL sampled_image のピッチは、pitch パラメーターから提供されます。構築された

SYCL sampled_image に は 、property_list のインスタンスを介して 0 個以上のプロパティーを提供できます。

表 47. sampled_image クラス・テンプレートのメンバー関数
メンバー関数説明

range<Dimensions> get_range() const

コンストラクターに渡される各次元の要素数から、イメージサイ
ズのレンジ・オブジェクトを返します。

range<Dimensions-1> get_pitch() const

Dimensions > 1 の場合にのみ利用できます。
イメージのピッチをバイト単位で表すレンジ・オブジェクトを返します。

size_t size() const noexcept

イメージの合計要素数を返します。
get_range()[0] * ... * get_range()[Dimensions-1] に等価です。

size_t byte_size() const noexcept

イメージストレージのサイズをバイト単位で返します。効率良くアクセスするため、イメージ要素、行、スライスがパディングされるため、バイト数は size() * 要素サイズ よりも大きくなる可能性があります。

template<typename...Ts>
auto get_access(Ts... args)

イ メ ー ジ と 提 供 さ れ た す べ て の 引 数 を sampled_image_accessor コンストラクターに渡して構築されたように、有効な
sampled_image_accessor を返します。
可能な実装:
return sampled_image_accessor {*this, args...};

第 4 章 SYCL プログラミング・インターフェイス | 131

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

template<typename...Ts>

イメージと提供されたすべての引数を host_sampled_image_auto get_host_access(Ts... args)

accessor コンストラクターに渡して構築されたかように、有効な
host_sampled_image_accessor を返します。
可能な実装:
return host_sampled_image_accessor {*this, args...};

4.7.3.3. イメージ・プロパティー
SYCL unsampled_image と sampled_image クラスを構築する際に提供できるプロパティーを表 48 に示します。
1.

namespace sycl {2.

namespace property {3.

namespace image {4.

class use_host_ptr {5.

public:6.

use_host_ptr() = default;

7.

};

8.
9.

class use_mutex {10.

public:11.

use_mutex(std::mutex& mutexRef);

12.
13.

std::mutex* get_mutex_ptr() const;

14.

};

15.
16.

class context_bound {17.

public:18.

context_bound(context boundContext);

19.
20.

context get_context() const;

21.

};

22.

} // namespace image

23.
24.

} // namespace property} // namespace sycl

表 48. SYCL イメージクラスによってサポートされるプロパティー
プロパティー説明

property::image::use_host_ptr

use_host_ptr プロパティーは、SYCL ランタイムが image のメ
モリーを割り当てず、代わりに提供されるホストポインターを直接使用する要件を追加します。これにより、SYCL ランタイムがホストに一時ストレージを割り当てるのを防ぎます。

132 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

プロパティー説明

property::image::use_mutex

このプロパティーは、SYCL image が所有するメモリーをプロパティーに提供されている std::mutex を介してアプリケーションと共有できる要件を追加します。std::mutex は、データが使用される際は常にロックされ、それ以外ではアンロックされます。
std::mutex が ラ ン タ イ ム で ロ ッ ク 解 除 さ れ る と 、 デ ー タ は
hostData と同期されます。

property::image::context_boundcontext_bound プロパティーは、SYCL image がプロパティーに提供される単一の SYCL context にだけ関連付けることが可能であるという要件を加えます。

イメージ・プロパティー・クラスのコンストラクターとメンバー関数を表 49 と表 50 に示します。
表 49. イメージ property クラスのコンストラクター
コンストラクター

説明

property::image::use_host_ptr::use_host_ptr()

SYCL use_host_ptr プロパティーのインスタンスを作成します。

property::image::use_mutex::use_mutex(std::mutex&指定された mutexRef パラメーターへの参照を使用して、SYCL

mutexRef)

use_mutex プロパティーのインスタンスを作成します。

property::image::context_bound::context_bound(context

SYCL context のコピーを使用して SYCL context_bound プロ

boundContext)

パティーのインスタンスを作成します。

表 50. イメージ property クラスのメンバー関数
メンバー関数説明

std::mutex* property::image::use_mutex::get_mutex_ptr()

SYCL use_mutex プ ロ パ テ ィ ー を 作 成 す る 際 に 指 定 し た

const

std::mutex を返します。

context property::image::context_bound::get_context()

SYCL context_bound プロパティーを作成する際に指定した

constcontext を返します。

4.7.3.4. イメージ同期規則
規則は 4.7.2.3 節で説明されるものと同じです。
イメージ・オブジェクトの存続期間中、関連するホストメモリーは SYCL ランタイムが利用可能な状態にしておく必要があり、イメージ・
オブジェクトが破棄されるまで関連するホストメモリーの内容は未定義です。イメージ・オブジェクトの値がコピーされると、ベースとなるイメージ・オブジェクトへの参照のみがコピーされます。ベースとなるイメージ・オブジェクトは参照カウントされます。ベースとなるイ
メージ・オブジェクトへのすべてのイメージ値参照が破棄された場合にのみ、実際のイメージ・オブジェクトが破棄されます。
イメージ・オブジェクトが関連するホストメモリーを使用して構築される場合、デストラクターはそのイメージ・オブジェクトのすべての
SYCL キューの操作が完了するまでブロックします。イメージデータの変更は、必要に応じて関連するホストメモリーにコピーされます。

第 4 章 SYCL プログラミング・インターフェイス | 133

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
破棄中に発生したエラーは、関連するコンテキストの非同期エラーハンドラーに報告されます。イメージ・オブジェクトがストレージ・オ
ブジェクトで構築されている場合、ストレージ・オブジェクトは、イメージ・オブジェクトの破棄時に行われる同期またはコピー動作を定義します。

4.7.4. SYCL データ管理クラスとホストメモリーの共有
SYCL ランタイムがメモリーを管理できるようにして、データの依存関係を許容するため、バッファーとイメージの 2 つのクラスが定義されています。それらのデフォルト動作では、データ管理クラスの構築中に「生の」ポインターが与えられ、SYCL オブジェクトが破棄されるまで完全な所有権を保持します。
ここでは、ホストメモリーを SYCL データクラスとして共有するか共有しないかに関して詳しく説明し、バッファークラスに例を示します。
同じ規則がイメージにも適用されます。

4.7.4.1. デフォルトの動作
SYCL バッファーを使用する場合、クラスのコンストラクターに渡されるポインターの所有権は、デフォルトで SYCL ランタイムに渡され、バッファーまたはイメージが破棄されるまで、そのポインターをホストで利用することはできません。4.7.6 節で定義されるように、
SYCL アプリケーションは host_accessor を介して SYCL バッファーが管理するメモリーコンテンツにアクセスできます。ただし、ホストアクセサーがコンストラクターで使用される元のホストアドレスと同期される保証はありません。
渡されるポインターは、バッファーが破棄される前に必要に応じてデータをホストにコピーバックする際に使用されるポインターです。
ホストポインターが指すメモリーはランタイムによって解放されることはなく、必要に応じてデータはデバイスからコピーされます。

4.7.4.2. ホストメモリーの SYCL 所有権
データの初期化に使用するホストメモリーがあり、バッファーが破棄された後にそのホストメモリーを使用しない場合、バッファーはホ
ストメモリーの完全な所有権を保持できます。
バッファーがホストポインターを所有する場合、デフォルトではコピーバックされません。この場合、SYCL アプリケーションはホスト
データへの一意なポインターを渡すことがあります。このポインターは、ランタイムによって内部的に利用されデバイス上のデータを初期化します。
例えば、次のように使用します。
1.

{

2.

auto ptr = std::make_unique<int>(-1234);

3.

buffer<int, 1> b { std::move(ptr), range { 1 } };4.

// ptr はすでに有効ではありません。

5.

// データをコピーし戻す場所がありません6.

}

ただし、オプションで buffer::set_final_data() を std::weak_ptr に設定することで、バッファー構築後に有効となる別のホスト・メモ
リー・アドレスにデータをコピーバックすることができます。
1.

{

2.

auto ptr = std::make_unique<int>(-42);

3.

buffer<int, 1> b { std::move(ptr), range { 1 } };4.

// ptr はすでに有効ではありません。

5.

// データをコピーし戻す場所がありません。

6.

// コピーし戻すには場所を指定します:7.

b.set_final_data(std::weak_ptr<int> { })134 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
8.

}

4.7.4.3. ホストメモリーの共有 SYCL 所有権
std::shared_ptr のインスタンスがバッファー・コンストラクターに渡されると、バッファー・オブジェクトとアプリケーションがメモリー領域を共有します。共有ポインターが継続してアプリケーションで使用される場合、データはバッファーまたはイメージからコピーバッ
クされ、バッファーやイメージが破棄された後にアプリケーションで利用できるようになります。
shared_ptr ポインターが空ではない場合、参照されるメモリーの内容がバッファーの初期化に使用されます。shared_ptr が空の場合、バッファーは初期化されていないメモリーで作成されます。
バッファーが破棄されデータが更新された可能性がある場合、ランタイム外で共有されるポインターのコピーが 0 であると、ユーザーがデータを読み取る共有ポインターは存在しません。従ってデータはコピーされず、アプリケーションでは結果を必要としないため、バッファーのデストラクターはデータ処理の終了を待機する必要はありません。
これは、バッファークラスの set_final_data() メンバー関数でオーバーライドできます。set_final_data() メンバー関数がデータを配置した場所にデータがコピーされるまで、バッファー・デストラクターは待機します (最終データが nullptr の場合は待機せずコピーし
ます)。
1.

{

2.

std::shared_ptr<int> ptr { data };

3.

{

4.

buffer<int, 1> b { ptr, range<2>{ 10,10 } };5.

// データを更新

6.

[...]

7.

} // ユーザー側に shared_ptr があるため、データはコピーバックされます

8.

}

1.

{

2.

std::shared_ptr<int> ptr { data };

3.

｛

4.

buffer<int, 1> b { ptr, range<2>{ 10, 10 } };5.

// データを更新

6.

[...]

7.

ptr.reset();8.
9.

} // ユーザー側に shared_ptr がないため、データはコピーバックされません｝

4.7.5. 同期プリミティブ
ユーザーが SYCL ランタイムと独自コード (マルチスレッドのメカニズムなど) でバッファーを同時に使用する際に host_accessor 使
わずに手動で同期を行う場合、適切なプロパティーを介して std::mutex をバッファー・コンストラクターに渡すことができます。
ランタイムは、データの使用中は常にミューテックスをロックし、データが不要になるとアンロックすることを保証します。
1.

{

2.

std::mutex m;

3.

auto shD = std::make_shared<int>(42)4.

sycl::buffer b { shD, { sycl::property::buffer::use_mutex { m } } };第 4 章 SYCL プログラミング・インターフェイス | 135

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
5.

{

6.

std::lock_guard lck { m };7.

// ユーザーデータをアクセス

8.

do_something(shD);

9.

/* m は、lck がスコープ外になると、このブロックの通常終了によって、

10.

例外がスローされた場合でもロックが解除されます */

11.
12.

}
}

ランタイムがミューテックスを解放すると、メンバー関数 set_final_data().によって最終的なデータのデスティネーションが変更されていない限り、データが共有ポインターにコピーバックされることが保証されます。

4.7.6. アクセサー
アクセサーは、バッファーまたはイメージによって管理されるデータへのアクセスと、デバイス上のローカルメモリーへのアクセスを提供し、カーネルのスケジュールを決定するメモリー・オブジェクトの要件を定義する 3 つの機能を提供します (詳細は 3.8.1 節を参照)。
アクセサーがプレースホルダーではない限り、メモリー・オブジェクトの要件はアクセサーの構築時に作成されます。プレースホルダーである場合、handler::require() を呼び出してコマンドにバインドされるときに要件が作成されます。
C++ にはアクセサーを実装するいくつかのクラスがあります・• accessor クラスは、コマンドから buffer データへのアクセスを提供します。
• host_accessor クラスは、コマンド外部にあるホストコードから buffer 内のデータへのアクセスを提供します。これらのアクセ
サーは通常、アプリケーションのスコープで使用されます。

• local_accessor クラスは、SYCL カーネル関数からデバイスのローカルメモリーへのアクセスを提供します。
• unsampled_image_accessor と sampled_image_accessor ク ラ ス は 、 コ マ ン ド 内 か ら unsampled_image お よ びsampled_image へのデータアクセスを提供します。

• host_unsampled_image_accessor と host_sampled_image_accessor クラスは、コマンド外部にあるホストコードから
unsampled_image と sampled_image データへのアクセスを提供します。これらのアクセサーは通常、アプリケーション・ス
コープで使用されます。
アクセサー・オブジェクトは、コマンドグループまたはアプリケーション・スコープのどちらかで、ホストコードを構築しなければなりません。コンストラクターがデータの同期による待機をブロックするかどうかは、アクセサーのタイプに依存します。コマンド内のデータへのアクセスを提供するこれらのアクセサーはブロックしません。代わりに、そのようなアクセサーはコマンドのスケジュールに影響する要件を定義します。ホストコードからのデータへのアクセスを提供するアクセサーは、データがホストで利用可能になるまでブロックします。
コマンド内でデータへのアクセスを提供するアクセサーでは、データにアクセスするメンバー関数はコマンド内からのみ呼び出すことができます。コマンドの外部からこれらのメンバー関数を呼び出すプログラムの構造は、適切ではありません。以下では、どのメンバー関数がこのカテゴリーに含まれるか詳しく説明します。

4.7.6.1. データタイプ
すべてのアクセサーには、アクセサーがアクセスする要素のタイプを指定する DataT テンプレート・パラメーターがあります。accessor
および host_accessor では、このタイプはベースとなるバッファー内のそれぞれの要素タイプと一致するか、そのタイプの const 修飾
されたバージョンである必要があります。

136 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
イメージアクセサー (unsampled_image_accessor、sampled_image_accessor、host_unsampled_image_accessor、および
host_sampled_image_accessor) の場合、DataT は、次のいずれかでなければなりません。

• int4 (vec<int32_t,4>)• uint4 (vec<uint32_t,4>)• float4 (vec<float,4>)• half4 (vec<half,4>)
local_accessor で許容される DataT については、4.7.6.11 節をご覧ください。

4.7.6.2. アクセスモード
大部分のアクセサーには、アクセサーがベースとなるデータを読み書きできるかを指定する AccessMode テンプレート・パラメーターがあります。この情報は、関連するコマンドの要件を定義する際にランタイムによって使用され、アクセサーを介してデータにアクセスする前にデバイスとの間でデータを転送する必要があるかどうかをランタイムに通知します。
表 51 の access_mode 列挙は、アクセサーの潜在的なモードを説明しています。ただし、すべてのアクセサークラスがすべてのモードをサポートするわけではないため、詳細についてはそれぞれのクラスの説明をご覧ください。
1.

namespace sycl {2.
3.

enum class access_mode ： /* 未定義 */ {

4.

read,

5.

write,

6.

read_write,

7.

discard_write,

8.

discard_read_write, // SYCL 2020 では非推奨

9.
10.

atomic// SYCL 2020 では非推奨// SYCL 2020 では非推奨

};

11.
12.

namespace access {13.

// レガシータイプ 「AccessMode」 は非推奨

14.
15.

using mode = sycl::access_mode;} // namespace access

16.
17.

} // namespace sycl

表 51. アクセサーが利用できるアクセスモードの列挙
access_mode

説明

access_mode::read

読み取り専用アクセス。

access_mode::write

書き込み専用アクセス。

access_mode::read_write

読み取りと書き込みアクセス。

第 4 章 SYCL プログラミング・インターフェイス | 137

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.3. デダクション・タグ
一部のアクセサーのコンストラクターは、コンストラクター・クラスのテンプレート引数を推定する際に使用される TagT パラメーターを受け取ります。表 51 のそれぞれのアクセスモードにはタグが関連付けられていますが、アクセスモードに加えてほかのテンプレー
ト・パラメーターを設定する追加タグがあります。以下は、実装が TagT パラメーターとして可能な値を提供する名前空間のスコープ変数を示しています。
1.

namespace sycl {2.
3.

inline constexpr __unspecified__ read_only;4.

inline constexpr __unspecified__ read_write;

5.

inline constexpr __unspecified__ write_only;

6.

inline constexpr __unspecified__ read_only_host_task;

7.

inline constexpr __unspecified__ read_write_host_task;

8.

inline constexpr __unspecified__ write_only_host_task;

9.
10.

} // namespace sycl

これらのタグの明確な意味は、構築されるアクセサークラスによって異なるため、以下に示すアクセサータイプに関連する項で詳しく説明します。

4.7.6.4. プロパティー
すべてのアクセサー・コンストラクターは、アクセサーのセマンティクスに影響する property_list パラメーターを受け取ります。表 52
は、アクセサー・プロパティーのすべてのセットを示し、それぞれのアクセサークラスを構築する際に許可されるプロパティーを示しています。
1.

namespace sycl {2.

namespace property {3.

struct no_init {};4.

} // namespace property

5.
6.
7.

inline constexpr property::no_init no_init;} // namespace sycl

138 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 52. アクセサーでサポートされるプロパティー
プロパティー

許可

説明

property::no_init

accessor host_accessor

このプロパティーは、アプリケーションが以前の値を読み取ることな

unsampled_image_accessor
host_unsampled_image_accessor

く、アクセサーのすべての要素に新しい値を書き込むことを期待する
場合に役立ちます。実装では、アクセサーのデータのコピーを回避する
ためこの情報を利用することもできます。以下に詳細を示します。
こ の プ ロ パ テ ィ ー は 、 access_mode::write ま た は access_mode::
read_write アクセスモードを持つアクセサーのみに許可されます。この
プロパティーを使用して、access_mode::read アクセサーを作成しようとすると、errc::invalid エラーコードで例外がスローされます。
このプロパティーの使い方は、アクセサーのベースとなるデータタイプ
DataT が暗黙のライフタイム型 (C++ コア言語で定義) であるかによって異なります。暗黙のライフタイム型である場合、アクセサーは不確定値を持つタイプのオブジェクトを暗黙的に作成します。アプリケーショ
ンはアクセサーの要素に値を書き込む必要はありませんが、アクセサーのバッファーやイメージに書き込まれていない要素は、バッ
ファーやイメージが以前に定義された値を持っていても不確定な値を受け取ります。これがレンジ付きアクセサーである場合、これはアクセ
サーのレンジ内の要素にのみ適用されます。レンジ外への未書き込み要素の値は保持されます。
DataT が暗黙のライフタイム型ではない場合、アクセサーは初期化されていないメモリーを割り当てるだけで、アプリケーションがメモリー内にオブジェクトを構築する責任があります (例えば、プレースメント
new を呼び出して)。ベースとなるバッファーの対応する要素に以前のオブジェクトが含まれていない場合を除き、アプリケーションはアクセサーの要素にオブジェクトを作成する必要があります。これがレンジ付きアクセサーである場合、これはアクセサーのレンジ内の要素にのみ適用されます。レンジ外のバッファー内のオブジェクトの内容は保持されます。

上記のように、property::no_init プロパティーでは、要素のタイプが暗黙のライフタイム型ではない場合 (対応するバッファー要素に以前のオブジェクトが含まれない場合を除く)、アプリケーションがアクセサーの要素にオブジェク
トを構築する必要があります。この要件の背景は、例えば、アクセサーを使用するコマンドが完了した後に、有効なオブジェクトが不確定バイトで上書きされるのを回避するためです。これは、DataT タイプが暗黙のライフタイム型であるかどうかにかかわりなく、コマンドの完了時に実装が無条件でデバイスからメモリーをコピー可能であることを意味します。
アクセサー・プロパティー・クラスのコンストラクターを表 53 に示します。
表 53. アクセサー・プロパティー・クラスのコンストラクター
コンストラクター

説明

property::no_init::no_init()

no_init プロパティー・インスタンスを作成します。

第 4 章 SYCL プログラミング・インターフェイス | 139

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.5. 読み取り専用アクセサー
AccessMode テンプレート・パラメーターを持つアクセサーは、テンプレート・パラメーターに access_mode::read を指定することで読み取り専用として宣言できます。読み取り専用アクセサーは、ベースとなるデータへの読み取り専用アクセスを提供し、メモリー・オブジェクトが構築される際に 「読み取り」 要件を設定します。
読み取り専用アクセサーの DataT テンプレート・パラメーターは、オプションで const 修飾できますが、アクセサーのセマンティクスは変更されません。例えば、const DataT と access_mode::read で宣言されたアクセサーは、DataT と access_mode::read で宣言されたアクセサーと同じセマンティクスを持ちます。
以下に説明するように、一部のアクセサータイプには DataT パラメーターが const 修飾されているかに応じて、AccessMode のデ
フォルト値が決まります。これにより、アクセスモードを明示的に指定することなく、読み取り専用アクセサーを宣言する方法が提供されます。
const 修飾された DataT は、読み取り専用アクセサーにのみ許可されます。const 修飾された DataT と access_mode::read 以外のアクセスモードを持つプログラムは不正形式であり、実装は診断を行う必要があります。
各アクセサークラスは、2 つの形式の読み取り専用アクセサー間での暗黙の変換も提供します。これにより、ほかのテンプレート・パラ
メーターが同一である限り、const DataT および access_mode::read タイプを持つアクセサーを DataT および access_mode::read
タイプのアクセサーに割り当てることができます。読み取り/書き込みアクセサーから、読み取り専用アクセサー形式への暗黙の変換もあります。これらの暗黙の変換については、アクセサークラスごとに以降で詳しく説明します。

4.7.6.6. アクセサーの要素をアクセス
accessor、host_accessor および local_accessor タイプのアクセサーは、0、1、2、または 3 次元にすることができます。ゼロ次元のア
クセサーは、その要素のベースとなるタイプへの暗黙の変換オペレーターと、要素のベースとなるタイプからオーバーロードされたコ
ピー/ムーブ代入演算子を介して、単一のスカラー要素へのアクセスを提供します。
これらのアクセサーの 1、2、または 3 次元の特殊化により、次の 2 つの方法でそれらに含まれる要素へのアクセスが提供されます。最初の方法は、アクセサーと同じ次元を持つ id クラスのインスタンスを取得する添字オペレーターを使用することです。2 番目の方法は、
3.11.2 節で示すように、単一の size_t 値を連続する添字オペレーターに渡すことです。
これらすべてのケースにおいて、包括される要素への参照は、読み取り専用アクセサーでは const DataT& タイプであり、それ以外のアクセサーでは DataT& タイプです。
すべてのタイプのアクセサーは、要素へのアクセスに使用できるインデックスのセットを定義するレンジを持ちます。バッファーアクセ
サーでは、これはベースとなるバッファーのレンジです。ただし、レンジ付きアクセサーの場合は、レンジはアクセサーのコンストラク
ターから取得されます。イメージアクセサーでは、ベースとなるイメージのレンジになりますローカルアクセサーは、アクセサーが構築される際にレンジを指定します。範囲外のインデックスで要素にアクセスすると未定義の例外が発生します。

4.7.6.7. コンテナーのインターフェイス
accessor、host_accessor、および local_accessor タイプのアクセサーは、ReversibleContainer の C++ 要件を満たします。この例外
は、local_accessor のみがベースとなるデータを所有することを意味します。
デストラクターは要素を破棄してメモリーを解放します。accessor と host_accessor タイプは、要素を破棄したりメモリーを解放することはありません。コンテナー・インターフェイスのイテレーターは、LegacyRandomAccessIterator の C++ 要件を満たし、ベースとなるポインター/参照はアクセサータイプで指定されるアドレス空間に対応します。多次元アクセサーの場合、イテレーターは 3.11.1 節
に従ってデータを線形化します。

140 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.8. レンジ付きアクセサー
accessor および host_accessor タイプのアクセサーは、コンストラクターにレンジとオフセットを提供することで、buffer の subrange から構築できます。これにより、アクセス可能な要素が指定される sub-range に制限され、デバイス間でコピーするメモリーの量を減らすなど、実装が特定の最適化を行えるようになります。
レンジ付きアクセサーが多次元である場合、sub-range が線形アドレス空間で隣接しないベースとなるバッファー内のメモリー領域を記述すことを可能にします。オーバーラップするまたはしない形式で、同じベースとなるバッファーに対し複数のレンジ付きアクセサーを構築することも許可されます。
レンジ付きアクセサーは、レンジ内にない範囲があっても、ベースとなるバッファー全体の要件を設けます。例えば、最初のコマンドがレンジ付きアクセサーを介してバッファーのある領域に書き込み、2 番目のコマンドがレンジ付きアクセサーで同じバッファーの重複しない領域から読み取りを行う場合、2 つのコマンドの要件はレンジ付きアクセサーの sub-range ではなく、バッファー全体にあるため、2 番目のコマンドは最初のコマンドの後にスケジュールする必要があります。
ベースとなるバッファー要素への参照を提供するアクセサーのメンバー関数の多くは、レンジ付きアクセサーのオフセットとレンジの影響を受けます。例えば、1 次元のレンジ付きアクセサーで operator[](0) を呼び出すと、アクセサーのオフセットで指示される位置にある要素への参照が返されます。これは、必ずしもバッファーの先頭要素である必要はありません。さらに、アクセサーのイテレーター関数は、sub-range 内にある要素に対してのみ繰り返されます。
唯一の例外は、get_pointer と get_multi_ptr メンバー関数であり、この関数はアクセサーのオフセットにかかわりなくベースとなる
バッファーの先頭へのポインターを返します。これらの関数を利用するアプリケーションは、ポインターを逆参照する前に手動でオフ
セ ッ ト を 追 加 す る 必 要 が あ り ま す 。 こ れ は 、 ア ク セ サ ー の レ ン ジ 外 の 要 素 に ア クセ ス す る と 未 定 義 の 動 作 と な る た め で す 。

レンジがゼロの範囲アクセサーの動作に変更はありません。ベースとなるバッファー全体の要件が作成され、要素にアクセスを試みると未定義の動作となります。

4.7.6.9. コマンドのバッファーアクセサー
accessor クラスは、SYCL カーネル関数またはホストタスクから buffer 内のデータへのアクセスを提供します。SYCL カーネル関数で使用されると、デバイスのグローバルメモリーを介してバッファーの内容にアクセスします。表 54 に示すように、2 つの形式のアクセサーは、AccessTarget テンプレート・パラメーターによって区別されます。どちらも次の AccessMode テンプレート・パラメーター値をサポートします: access_mode::read、access_mode::write、および access_mode::read_write。
表 54. バッファーアクセサーのアクセスターゲットの説明
ターゲットをアクセス意味

target::device

デバイスのグローバルメモリーを介して SYCL カーネル関数から
バッファーにアクセスします。

target::host_task

ホストタスクからバッファーにアクセスします。

アクセスターゲットを target::device に指定し、ホストタスクから accessor を取得するプログラムは、interop_handle を介して相互運用性のためにのみアクセサーを使用できます。それ以外は、未定義の動作となります。
アクセスターゲットを target::host_task に指定し、SYCL カーネル関数から accessor を使用するプログラムも未定義の動作となります。

第 4 章 SYCL プログラミング・インターフェイス | 141

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
アクセサーの次元数はベースとなるバッファーと一致しなければなりませんが、バッファーが 1 次元の場合は特別なケースがあります。
この場合、アクセサーは 1 次元であっても、ゼロ次元であってもかまいません。ゼロ次元のアクセサーはバッファーの最初の要素にのみアクセスできますが、1 次元バッファーはバッファー全体にアクセスできます。
特定の accessor コンストラクターは、プレースホルダー・アクセサーを作成します。そのようなアクセサーはバッファーにバインドされ、アクセスターゲットやアクセスモードのセマンティクスが定義されます。ただし、プレースホルダー・アクセサーはコマンドグループにはまだバインドされていません。このようなアクセサーをコマンドで使用する前に、handler::require() を呼び出してアクセサーをバインドする必要があります。プレースホルダー・アクセサーが、handler::require() でコマンドグループに最初にバインドされることなく引数としてコマンドに渡されると、実装はコマンドが送信されたときに errc::kernel_argument エラーコードで同期例外をスローします。

4.7.6.9.1. バッファー・コマンド・アクセサーのインターフェイス
accessor クラスの概要を以下に示します。ここでは、target::device または target::host_task に特化したインターフェイスを示しています。一部のクラスタイプとメンバー関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については
4.7.6.12 節で説明します。表 79 と表 55 にメンバータイプ、表 56 にコンストラクター、表 80 と表 57 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。アクセサータイプ間での有効な暗黙の変換については、4.7.6.9.3 節を参照してください。さらに、同じタイプのアクセサーは、ホスト・アプリケーションと SYCL カーネル関数の両方で同一である必要があります。
1.

namespace sycl {2.
3.

enum class target ： /* 未定義 */ {4.

device,5.

host_task,

6.

constant_buffer,// 非推奨7.

local,// 非推奨8.

host_buffer,// 非推奨9.
10.

global_buffer = device // 非推奨
};

11.
12.

namespace access {13.

// レガシータイプ 「access::__declspec(target)」 は非推奨です14.

using sycl::target;

15.
16.

enum class placeholder ： /* 未定義 */ { // 非推奨

17.

false_t,18.
19.

true_t};20.
21.

} // namespace access

22.
23.
24.

template <typename DataT,25.

int Dimensions = 1,

26.

access_mode AccessMode =27.

(std::is_const_v<DataT> ? access_mode::read28.

: access_mode::read_write),29.

target AccessTarget = target::device,

30.
31.
32.

access::placeholder IsPlaceholder = access::placeholder::false_t>class accessor {public:142 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
33.
34.

using value_type = // 読み取り専用アクセサーの const DataT、それ以外は DataT__value_type__;35.

using reference = value_type&;

36.

using const_reference = const DataT&;

37.

template <access::decorated IsDecorated>

38.

using accessor_ptr =39.

__pointer_class__;// multi_ptr から value_type へのターゲットアドレス空間、// access_mode::host_task には指定されていません

40.

using iterator = __unspecified_iterator__ <value_type>;

41.

using const_iterator = __unspecified_iterator__ <const value_type>;

42.

using reverse_iterator = std::reverse_iterator<iterator>;

43.

using const_reverse_iterator = std::reverse_iterator<const_iterator>;

44.

using difference_type = typename std::iterator_traits<iterator>::difference_type;45.

using size_type = size_t;

46.
47.

accessor();

48.
49.

/* 次のときにのみ利用可能: (Dimensions == 0) */50.

template <typename AllocatorT>

51.

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,

52.

const property_list& propList = {});

53.
54.

/* 次のときにのみ利用可能: (Dimensions == 0) */55.

template <typename AllocatorT>

56.

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,

57.

handler& commandGroupHandlerRef, const property_list& propList = {});

58.
59.

/* 次のときにのみ利用可能: (Dimensions > 0) */60.

template <typename AllocatorT>

61.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

62.

const property_list& propList = {});

63.
64.

/* 次のときにのみ利用可能: (Dimensions > 0) */65.

template <typename AllocatorT, typename TagT>

66.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef, TagT tag,

67.

const property_list& propList = {});

68.
69.

/* 次のときにのみ利用可能: (Dimensions > 0) */70.

template <typename AllocatorT>

71.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

72.

handler& commandGroupHandlerRef, const property_list& propList = {});

73.
74.

/* 次のときにのみ利用可能: (Dimensions > 0) */75.

template <typename AllocatorT, typename TagT>

76.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

77.

handler& commandGroupHandlerRef, TagT tag,78.

const property_list& propList = {});

79.
80.

/* 次のときにのみ利用可能: (Dimensions > 0) */81.

template <typename AllocatorT>

82.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

83.

range<Dimensions> accessRange, const property_list& propList = {});

84.

第 4 章 SYCL プログラミング・インターフェイス | 143

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ85.

/* 次のときにのみ利用可能: (Dimensions > 0) */86.

template <typename AllocatorT, typename TagT>

87.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

88.

range<Dimensions> accessRange, TagT tag,89.

const property_list& propList = {});

90.
91.

/* 次のときにのみ利用可能: (Dimensions > 0) */92.

template <typename AllocatorT>

93.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

94.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

95.

const property_list& propList = {});

96.
97.

/* 次のときにのみ利用可能: (Dimensions > 0) */98.

template <typename AllocatorT, typename TagT>

99.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

100.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

101.

TagT tag, const property_list& propList = {});

102.
103.

/* 次のときにのみ利用可能: (Dimensions > 0) */104.

template <typename AllocatorT>

105.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

106.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

107.

const property_list& propList = {});

108.
109.

/* 次のときにのみ利用可能: (Dimensions > 0) */110.

template <typename AllocatorT, typename TagT>

111.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

112.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

113.

TagT tag, const property_list& propList = {});

114.
115.

/* 次のときにのみ利用可能: (Dimensions > 0) */116.

template <typename AllocatorT>

117.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

118.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

119.

id<Dimensions> accessOffset, const property_list& propList = {});

120.
121.

/* 次のときにのみ利用可能: (Dimensions > 0) */122.

template <typename AllocatorT, typename TagT>

123.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

124.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

125.

id<Dimensions> accessOffset, TagT tag,126.

const property_list& propList = {});

127.
128.

/* -- 共通インターフェイスのメンバー -- */

129.
130.

void swap(accessor& other);

131.
132.

bool is_placeholder() const;

133.
134.

size_type byte_size() const noexcept;

135.
136.

size_type size() const noexcept;

144 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
137.
138.

size_type max_size() const noexcept;

139.
140.

// 非推奨141.

size_t get_size() const;

142.
143.

// 非推奨144.

size_t get_count() const;

145.
146.

bool empty() const noexcept;

147.
148.

/* 次のときにのみ利用可能: (Dimensions > 0) */149.

range<Dimensions> get_range() const;

150.
151.

/* 次のときにのみ利用可能: (Dimensions > 0) */152.

id<Dimensions> get_offset() const;

153.
154.

/* 次のときにのみ利用可能: (Dimensions == 0) */155.

operator reference() const;

156.
157.

/* 次のときにのみ利用可能: (Dimensions > 0) */158.

reference operator[](id<Dimensions> index) const;

159.
160.

/* 次のときにのみ利用可能: (Dimensions > 1) */161.

__unspecified__ operator[](size_t index) const;

162.
163.

/* 次のときにのみ利用可能: (AccessMode != access_mode::atomic && Dimensions == 1) */164.

reference operator[](size_t index) const;

165.
166.

/* 非推奨167.

次のときにのみ利用可能: (AccessMode == access_mode::atomic && Dimensions == 0) */168.

operator cl::sycl::atomic<DataT, access::address_space::global_space> () const;

169.
170.

/* 非推奨171.

次のときにのみ利用可能: (AccessMode == access_mode::atomic && Dimensions == 1) */172.

cl::sycl::atomic<DataT, access::address_space::global_space> operator[](173.

id<Dimensions> index) const;

174.
175.

std::add_pointer_t<value_type> get_pointer() const noexcept;

176.
177.

template <access::decorated IsDecorated>

178.

accessor_ptr<IsDecorated> get_multi_ptr() const noexcept;

179.
180.

iterator begin() const noexcept;

181.
182.

iterator end() const noexcept;

183.
184.

const_iterator cbegin() const noexcept;

185.
186.

const_iterator cend() const noexcept;

187.
188.

reverse_iterator rbegin() const noexcept;

第 4 章 SYCL プログラミング・インターフェイス | 145

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
189.
190.

reverse_iterator rend() const noexcept;

191.
192.

const_reverse_iterator crbegin() const noexcept;

193.
194.
195.

const_reverse_iterator crend() const noexcept;
};

196.
197.

} // namespace sycl

表 55. accessor クラスのメンバータイプ
メンバーのタイプ

説明

template <access::decorated IsDecorated> accessor_ptr(AccessTarget == target::device) の場合:
multi_ptr<value_type,access::address_space::global_space, IsDecorated>。
このタイプの定義は、(AccessTarget == target::host_task) の場合は指定されません。

表 56. accessor クラスのコンストラクター
コンストラクター

説明

accessor()

次の事後条件を満たす空のアクセサーを作成します。

•(empty() == true)•

すべてのサイズ照会は 0 を返します。

•

get_pointer() と get_multi_ptr() の戻り値は未定義です。

•

メモリーアクセスを行うと未定義の動作となります。

デフォルトで作成されたアクセサーは SYCL カーネル関数に渡すことはできますが、コマンド・グループ・ハンドラーに登録することはできません。
template <typename AllocatorT>
accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
const property_list& propList = {})(Dimensions == 0) の場合にのみ利用できます。
buffer の最初の要素にアクセスするプレースホルダー accessor
を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions == 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連するキューの SYCL カーネ
ル関数内の buffer の最初の要素にアクセスする accessor を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

146 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, const property_list& propList = {})buffer にアクセスするプレースホルダー accessor を作成します。オプションの property_list は作成されたアクセサーのプロ
パティーを提供します。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
buffer にアクセスするプレースホルダー accessor を作成します。tag は 4.7.6.9.2 節で説明されるように、アクセサーのテンプ
レート引数を推定するために使用されます。オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内の buffer の最初の要素にアクセスする accessor を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内の buffer の最初の要素にアクセスする accessor を作成します。tag は 4.7.6.9.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭から始まります。オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭から始まります。tag は 4.7.6.9.2
節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

第 4 章 SYCL プログラミング・インターフェイス | 147

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭からのオフセットから始まります。
オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
id<Dimensions> accessOffset,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭からのオフセットから始まります。
tag は 4.7.6.9.2 節で説明されるように、アクセサーのテンプレー
ト引数を推定するために使用されます。オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーである accessor を作成します。レンジはbuffer の 先 頭 か ら 始 ま り ま す 。 ア ク セ サ ー は 、commandGroupHandlerRef に関連するキューの SYCL カーネ
ル関数内でのみ使用できます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーである accessor を作成します。レンジはbuffer の 先 頭 か ら 始 ま り ま す 。 ア ク セ サ ー は 、commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内でのみ使用できます。tag は 4.7.6.9.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。
オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

148 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})レンジ付きアクセサーである accessor を作成します。レンジはbuffer の先頭からのオフセットから始まります。アクセサーは、
commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内でのみ使用できます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

template <typename AllocatorT, typename TagT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
id<Dimensions> accessOffset,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーである accessor を作成します。レンジはbuffer の先頭からのオフセットから始まります。アクセサーは、
commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内でのみ使用できます。tag は 4.7.6.9.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

表 57. accessor クラスのメンバー関数
メンバー関数説明

void swap(accessor& other);

現在のアクセサーの内容を other の内容とスワップします。

bool is_placeholder() const

アクセサーがプレースホルダーとして構築された場合 true を返します。それ以外は false を返します

id<Dimensions> get_offset() const(Dimensions > 0) の場合にのみ利用できます。
これがレンジ付きアクセサーである場合、アクセサーの構築時に指定されたオフセットを返します。その他のアクセサーでは、デフォルトで構築された id<Dimensions>{} を返します。

template <access::decorated IsDecorated>

レンジがバッファーの先頭から始まらないレンジ付きアクセサー

accessor_ptr<IsDecorated> get_multi_ptr() const noexcept であっても、アクセサーのベースであるバッファーの先頭である
multi_ptr を返します。アクセサーが空の場合、戻り値は不定です。
この関数は、コマンド内からのみ呼び出すことができます。

第 4 章 SYCL プログラミング・インターフェイス | 149

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

const accessor& operator=(const value_type& other) const (AccessMode != access_mode::atomic && Dimensions == 0)の場合にのみ使用できます。
アクセサーによってアクセスされる単一要素への参照を返します。
この関数は、コマンド内からのみ呼び出すことができます。
const accessor& operator=(value_type&& other) const(AccessMode != access_mode::atomic && Dimensions == 0)の場合にのみ使用できます。
アクセサーによってアクセスされる単一要素への参照を返します。
この関数は、コマンド内からのみ呼び出すことができます。

4.7.6.9.2. バッファー・コマンド・アクセサーのデダクション・タグ
一部の accessor のコンストラクターは、テンプレート引数を推定する際に使用される TagT パラメーターを受け取ります。このパラメーターの許容値は、表 58 にアクセスモードとアクセサーターゲットとともに示します。
表 58. accessor の構築に使用可能なタグの列挙
タグ値

アクセスモード

アクセサーのターゲット

read_write

access_mode::read_write

target::device

read_only

access_mode::readtarget::device

write_only

access_mode::write

target::device

read_write_host_task

access_mode::read_write

target::host_task

read_only_host_task

access_mode::readtarget::host_task

write_only_host_task

access_mode::write

target::host_task

4.7.6.9.3. 読み取り専用バッファー・コマンド・アクセサーと暗黙の変換
表 59 は、読み取り専用アクセサーである target::device または target::host_task による accessor の特殊化を示しています。
ほかのすべてのテンプレート・パラメーターが同一である場合、これらの特殊化間では暗黙の変換が行われます。
表 59. 読み取り専用の accessor の特殊化
データタイプ

アクセスモード

const 修飾されていません

access_mode::read

150 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

データタイプ

アクセスモード

const 修飾されています

access_mode::read

ほかのすべてのテンプレート・パラメーターが同一である場合、表 60 に示す読み取り/書き込みの特殊化から、表 59 に示す読み取り専用特殊化への暗黙の変換もあります。
表 60. 読み取り/書き込みの host_accessor の特殊化
データタイプ

アクセスモード

const 修飾されていません

access_mode::read_write

4.7.6.9.4. accessor クラスの非推奨の機能
ここで定義される機能は非推奨であり、将来の仕様では削除される可能性があります。

4.7.6.9.4.1. エイリアス名
列挙値 target::global_buffer は target:::device のエイリアスであり、エイリアスと同じタイプを持ちます。
列挙型 AccessTarget は target のエイリアスであり、列挙型 AccessMode は access_mode のエイリアスです。

4.7.6.9.4.2. アクセスモードの破棄
アクセスモード access_mode::discard_write に特殊化された accessor インスタンスは、プロパティー property::no_init で構築されたモード access_mode::write の accessor インスタンスと同じ動作をします。
アクセスモード access_mode::discard_read_write に特殊化された accessor インスタンスは、プロパティー property::no_init で構築されたモード access_mode::read_write の accessor インスタンスと同じ動作となります。

4.7.6.9.4.3. プレースホルダー・テンプレート・パラメーター
accessor インスタンスがプレースホルダーであるかにかかわりなく、accessor テンプレート・パラメーター IsPlaceholder を指定できます。これは、インスタンスの作成に使用されるコンストラクターによってのみ決定されます。
関連タイプ access::placeholder も非推奨になりました。

4.7.6.9.4.4. target::device を特殊化する追加のメンバー関数
target::device による accessor クラスの特殊化には、表 61 で示す追加のメンバー関数があります。
表 61. accessor クラスの非推奨なメンバー関数
メンバー関数説明

size_t get_size() const

byte_size() と同じ値を返します。

size_t get_count() const

size() と同じ値を返します。

第 4 章 SYCL プログラミング・インターフェイス | 151

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.9.4.5. target::constant_buffer によるアクセサーの特殊化
accessor クラスは、ターゲット target::constant_buffer で特殊化されている場合があります。これにより、SYCL カーネル関数内でデバイスの定数メモリーを介してバッファーの内容にアクセスできるアクセサーが生成されます。
ほかの accessor の特殊化と同様に、次元数はベースとなるバッファーと一致しなければなりませんが、バッファーが 1 次元の場合は特別なケースがあります。この場合、アクセサーは 1 次元であっても、ゼロ次元であってもかまいません。ゼロ次元のアクセサーはバッ
ファーの最初の要素にのみアクセスできますが、1 次元バッファーはバッファー全体にアクセスできます。
accessor の特殊化は、アクセスモード access_mode::read でのみ使用できます。
このアクセサータイプは、プレースホルダー・アクセサーとして構築できます。プレースホルダーであるほかの accessor の特殊化のよ
うに、プレースホルダー・アクセサーをコマンドに渡す前に、handler::require() を呼び出す必要があります。アプリケーションが、プ
レースホルダー・アクセサーの handler::require() を呼び出さない場合、実装はコマンドが送信されると errc::kernel_argument エ
ラーコードで同期例外をスローします。
accessor 特殊化の概要を以下に示します。一部のクラスタイプとへ異なる関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については 4.7.6.9.4.8 節で説明します。表 68 にメンバータイプ、表 62 にコンストラクター、表 69 と表 63 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。さらに、同じタイプのアクセサーは比較可能である必要があります。
1.

namespace sycl {2.
3.

template <typename DataT,

4.

int Dimensions,5.

access_mode AccessMode,6.

target AccessTarget

7.
8.
9.

access::placeholder IsPlaceholder>class accessor {public:10.

using value_type = const DataT;

11.

using reference = const DataT&;

12.

using const_reference = const DataT&;

13.
14.

/* 次のときにのみ利用可能: (Dimensions == 0) */15.

template <typename AllocatorT>

16.

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,

17.

const property_list& propList = {});

18.
19.

/* 次のときにのみ利用可能: (Dimensions == 0) */20.

template <typename AllocatorT>

21.

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,

22.

handler& commandGroupHandlerRef, const property_list& propList = {});

23.
24.

/* 次のときにのみ利用可能: (Dimensions > 0) */25.

template <typename AllocatorT>

26.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

27.

const property_list& propList = {});

28.
29.

/* 次のときにのみ利用可能: (Dimensions > 0) */152 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
30.

template <typename AllocatorT>

31.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

32.

handler& commandGroupHandlerRef, const property_list& propList = {});

33.
34.

/* 次のときにのみ利用可能: (Dimensions > 0) */35.

template <typename AllocatorT>

36.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

37.

range<Dimensions> accessRange, const property_list& propList = {});

38.
39.

/* 次のときにのみ利用可能: (Dimensions > 0) */40.

template <typename AllocatorT>

41.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

42.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

43.

const property_list& propList = {});

44.
45.

/* 次のときにのみ利用可能: (Dimensions > 0) */46.

template <typename AllocatorT>

47.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

48.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

49.

const property_list& propList = {});

50.
51.

/* 次のときにのみ利用可能: (Dimensions > 0) */52.

template <typename AllocatorT>

53.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

54.

handler& commandGroupHandlerRef, range<Dimensions> accessRange,

55.

id<Dimensions> accessOffset, const property_list& propList = {});

56.
57.

/* -- 共通インターフェイスのメンバー -- */

58.
59.

bool is_placeholder() const;

60.
61.

size_t get_size() const noexcept;

62.
63.

size_t get_count() const noexcept;

64.
65.

/* 次のときにのみ利用可能: (Dimensions > 0) */66.

range<Dimensions> get_range() const;

67.
68.

/* 次のときにのみ利用可能: (Dimensions > 0) */69.

id<Dimensions> get_offset() const;

70.
71.

/* 次のときにのみ利用可能: (Dimensions == 0) */72.

operator reference() const;

73.
74.

/* 次のときにのみ利用可能: (Dimensions > 0) */75.

reference operator[](id<Dimensions> index) const;

76.
77.

/* 次のときにのみ利用可能: (Dimensions > 1) */78.

__unspecified__ operator[](size_t index) const;

79.
80.

/* 次のときにのみ利用可能: (Dimensions == 1) */81.

reference operator[](size_t index) const;

第 4 章 SYCL プログラミング・インターフェイス | 153

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
82.
83.
84.

constant_ptr<DataT> get_pointer() const noexcept;
};

85.
86.

} // namespace sycl

表 62. 非推奨の定数アクセサーのコンストラクター
コンストラクター

説明

template <typename AllocatorT>(Dimensions == 0) の場合にのみ利用できます。

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
const property_list& propList = {})buffer の最初の要素にアクセスするプレースホルダー accessor
を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions == 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連するキューの SYCL カーネ
ル関数内の buffer の最初の要素にアクセスする accessor を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
buffer にアクセスするプレースホルダー accessor を作成します。オプションの property_list は作成されたアクセサーのプロ
パティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連する queue の SYCL カー
ネル関数内の buffer の最初の要素にアクセスする accessor を作成します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭から始まります。オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

154 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})レンジ付きアクセサーであるプレースホルダー accessor を作成します。レンジは buffer の先頭からのオフセットから始まります。
オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーである accessor を作成します。レンジはbuffer の 先 頭 か ら 始 ま り ま す 。 ア ク セ サ ー は 、commandGroupHandlerRef に関連するキューの SYCL カー
ネル関数内でのみ使用できます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, handler& commandGroupHandlerRef,
range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
レンジ付きアクセサーである accessor を作成します。レンジはbuffer の先頭からのオフセットから始まります。アクセサーは、
commandGroupHandlerRef に関連するキューの SYCL カーネ
ル関数内でのみ使用できます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

表 63. 非推奨の定数アクセサーのメンバー関数
メンバー関数説明

bool is_placeholder() const

アクセサーが placeholder として作成されている場合 true を返し、そうでない場合は false を返します。

id<Dimensions> get_offset() const(Dimensions > 0) の場合にのみ利用できます。
これがレンジ付きアクセサーである場合、アクセサーが構築されたときに指定されたオフセットを返します。それ以外は、デフォル
トで構築された id<Dimensions>{} を返します。

第 4 章 SYCL プログラミング・インターフェイス | 155

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

constant_ptr<DataT> get_pointer() const noexcept

レンジがバッファーの先頭から始まらないレンジ付きアクセサーであっても、アクセサーのベースであるバッファーの先頭である
multi_ptr を返します。アクセサーが空の場合、戻り値は不定です。

4.7.6.9.4.6. target::host_buffer によるアクセサーの特殊化
accessor クラスは、ターゲット target::host_buffer で特殊化されていることがあります。これにより、host_accessor と同様のホスト
アクセサーが生成されます。この特殊化は、コマンド外部にあるホストコードから buffer 内へのデータアクセスを可能にし、要求されたデータがホストで利用可能になるまで、この特殊化のコンストラクターをブロックします。
ほかの accessor の特殊化と同様に、次元数はベースとなるバッファーと一致しなければなりませんが、バッファーが 1 次元の場合は特別なケースがあります。この場合、アクセサーは 1 次元であっても、ゼロ次元であってもかまいません。ゼロ次元のアクセサーはバッ
ファーの最初の要素にのみアクセスできますが、1 次元バッファーはバッファー全体にアクセスできます。
この accessor の特殊化は、access_mode::atomic を除くすべてのアクセスモードで利用できます。
accessor 特殊化の概要を以下に示します。一部のクラスタイプとメンバー関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については 4.7.6.9.4.8 節で説明します。表 68 にメンバータイプ、表 64 にコンストラクター、表 69 と表 65 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。さらに、同じタイプのアクセサーは比較可能である必要があります。
1.

namespace sycl {2.
3.

template <typename DataT,

4.

int Dimensions,5.

access_mode AccessMode,6.

target AccessTarget,

7.
8.
9.
10.
11.

access::placeholder IsPlaceholder>class accessor {public:using value_type = // access_mode::read の const DataT、それ以外は DataT__value_type__;12.

using reference = value_type&;

13.

using const_reference = const DataT&;

14.
15.

/* 次のときにのみ利用可能: (Dimensions == 0) */16.

template <typename AllocatorT>

17.

accessor(buffer<DataT, 1, AllocatorT>&bufferRef,

18.

const property_list& propList = {});

19.
20.

/* 次のときにのみ利用可能: (Dimensions > 0) */21.

template <typename AllocatorT>

22.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

23.

const property_list& propList = {});

24.
25.

/* 次のときにのみ利用可能: (Dimensions > 0) */156 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
26.

template <typename AllocatorT>

27.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

28.

range<Dimensions> accessRange, const property_list& propList = {});

29.
30.

/* 次のときにのみ利用可能: (Dimensions > 0) */31.

template <typename AllocatorT>

32.

accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

33.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

34.

const property_list& propList = {});

35.
36.

/* -- 共通インターフェイスのメンバー -- */

37.
38.

bool is_placeholder() const;

39.
40.

size_t get_size() const;

41.
42.

size_t get_count() const;

43.
44.

/* 次のときにのみ利用可能: (Dimensions > 0) */45.

range<Dimensions> get_range() const;

46.
47.

/* 次のときにのみ利用可能: (Dimensions > 0) */48.

id<Dimensions> get_offset() const;

49.
50.

/* 次のときにのみ利用可能: (Dimensions == 0) */51.

operator reference() const;

52.
53.

/* 次のときにのみ利用可能: (Dimensions > 0) */54.

reference operator[](id<Dimensions> index) const;

55.
56.

/* 次のときにのみ利用可能: (Dimensions > 1) */57.

__unspecified__ operator[](size_t index) const;

58.
59.

/* 次のときにのみ利用可能: (Dimensions == 1) */60.

reference operator[](size_t index) const;

61.
62.
63.

std::add_pointer_t<value_type> get_pointer() const noexcept;
};

64.
65.

} // namespace sycl

表 64. 非推奨のホスト・バッファー・アクセサーのコンストラクター
コンストラクター

説明

template <typename AllocatorT>(Dimensions == 0) の場合にのみ利用できます。

accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
const property_list& propList = {})ホスト上の buffer の最初の要素に直ちにアクセスする accessorを構築します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

第 4 章 SYCL プログラミング・インターフェイス | 157

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, const property_list& propList = {})ホスト上の buffer に直ちにアクセスする accessor を構築します。オプションの property_list は作成されたアクセサーのプロ
パティーを提供します。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上のバッファーに直ちにアクセスするレンジ付きアクセサーである accessor を作成します。レンジは buffer の先頭から始まります。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

template <typename AllocatorT>
accessor(buffer<DataT, Dimensions, AllocatorT>&
bufferRef, range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上のバッファーに直ちにアクセスするターゲットアクセ
サーである accessor を作成します。レンジは buffer の先頭からのオフセットから始まります。オプションの property_list は構築されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

表 65. 非推奨のホスト・バッファー・アクセサーのメンバー関数
メンバー関数説明

bool is_placeholder() const

常に false を返します。

id<Dimensions> get_offset() const(Dimensions > 0) の場合にのみ利用できます。
これがレンジ付きアクセサーである場合、アクセサーが構築されたときに指定されたオフセットを返します。それ以外は、デフォル
トで構築された id<Dimensions>{} を返します。

std::add_pointer_t<value_type> get_pointer() const

レンジがバッファーの先頭から始まらないレンジ付きアクセサー

noexcept

であっても、アクセサーのベースであるバッファーの先頭へのポイ
ンターを返します。アクセサーが空の場合、戻り値は不定です。

4.7.6.9.4.7. target::local によるアクセサーの特殊化
accessor クラスは、ターゲットの target::local に特殊化されることがあります。これにより、local_accessor と同じセマンティクスと制限を持つローカルアクセサーが生成されます。
この accessor の特殊化は、アクセスモード access_mode::read_write と access_mode::atomic でのみ利用できます。

158 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
accessor 特殊化の概要を以下に示します。一部のクラスタイプとメンバー関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については 4.7.6.9.4.8 節で説明します。表 68 にメンバータイプ、表 66 にコンストラクター、表 69 と表 67 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。さらに、同じタイプのアクセサーは比較可能である必要があります。
1.

namespace sycl {2.
3.

template <typename DataT,

4.

int Dimensions,5.

access_mode AccessMode,6.

target AccessTarget,

7.
8.
9.

access::placeholder IsPlaceholder>class accessor {public:10.

using value_type = DataT;

11.

using reference = DataT&;

12.

using const_reference = const DataT&;

13.
14.

/* 次のときにのみ利用可能: (Dimensions == 0) */15.

accessor(handler& commandGroupHandlerRef,

16.

const property_list& propList = {});

17.
18.

/* 次のときにのみ利用可能: (Dimensions > 0) */19.

accessor(range<Dimensions> allocationSize, handler&commandGroupHandlerRef,

20.

const property_list& propList = {});

21.
22.

/* -- 共通インターフェイスのメンバー -- */

23.
24.

size_t get_size() const;

25.
26.

size_t get_count() const;

27.
28.

/* 次のときにのみ利用可能: (Dimensions > 0) */29.

range<Dimensions> get_range() const;

30.
31.

/* 次のときにのみ利用可能: (AccessMode == access_mode::read_write && Dimensions == 0) */32.

operator reference() const;

33.
34.

/* 次のときにのみ利用可能: (AccessMode == access_mode::read_write && Dimensions >35.

reference operator[](id<Dimensions> index) const;

0) */

36.
37.

/* 次のときにのみ利用可能: (Dimensions > 1) */38.

__unspecified__ operator[](size_t index) const;

39.
40.

/* 次のときにのみ利用可能: (AccessMode == access_mode::read_write && Dimensions == 1) */41.

reference operator[](size_t index) const;

42.
43.

/* 次のときにのみ利用可能: (AccessMode == access_mode::atomic && Dimensions == 0) */44.

operator atomic<DataT, access::address_space::local_space> () const;

45.

第 4 章 SYCL プログラミング・インターフェイス | 159

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ46.

/* 次のときにのみ利用可能: (AccessMode == access_mode::atomic && Dimensions > 0) */47.

atomic<DataT, access::address_space::local_space> operator[](id<Dimensions> index) const;

48.
49.

/* 次のときにのみ利用可能: (AccessMode == access_mode::atomic && Dimensions == 1) */50.

atomic<DataT, access::address_space::local_space> operator[](size_t index) const;

51.
52.
53.

local_ptr<DataT> get_pointer() const noexcept;
};

54.
55.

} // namespace sycl

表 66. 非推奨のローカルアクセサーのコンストラクター
コンストラクター

説明

accessor(handler& commandGroupHandlerRef,(Dimensions == 0) の場合にのみ利用できます。

const property_list& propList = {})commandGroupHandlerRef に関連付けられたキュー上の
SYCL カーネル関数内の単一の DataT 要素のローカルメモリーにアクセスする accessor インスタンスを構築します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。

accessor(range<Dimensions> allocationSize,
handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
commandGroupHandlerRef に関連付けられたキュー上の
SYCL カーネル関数内の DataT 配列要素のローカルメモリーにアクセスする accessor インスタンスを構築します。配列内の要素数は、allocationSize で定義されます。オプションのproperty_list は構築されたアクセサーのプロパティーを提供します。

表 67. 非推奨のローカルアクセサーのメンバー関数
メンバー関数説明

operator atomic<DataT,(AccessMode == access_mode::atomic && Dimensions ==access::address_space::local_space>() const

0) の場合にのみ利用できます。
このアクセサーがアクセスする work-group のローカルメモ
リーに格納されている要素へのアトミックアクセスを提供する
DataT タイプの atomic インスタンスを返します。

atomic<DataT, access::address_space::local_space>(AccessMode == access_mode::atomic && Dimensions >operator[](id<Dimensions> index) const

0) の場合にのみ利用できます。
index で指定されるインデックスで、このアクセサーがアクセスする work-group のローカルメモリーに格納されている要素へのアトミックアクセスを提供する DataT タイプの atomic イン
スタンスを返します。

160 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

atomic<DataT, access::address_space::local_space>(AccessMode == access_mode::atomic && Dimensions ==operator[](size_t index) const

1) の場合にのみ使用できます。
index で指定されるインデックスで、このアクセサーがアクセスする work-group のローカルメモリーに格納されている要素へのアトミックアクセスを提供する DataT タイプの atomic イン
スタンスを返します。

local_ptr<DataT> get_pointer() const noexcept

このアクセサーがアクセスする work-group のローカルメモ
リーへの multi_ptr を返します。アクセサーが空の場合、戻り値は不定です。

4.7.6.9.4.8. 非推奨のアクセサーの共通メンバー
target::constant_buffer、target::host_buffer および target::local を使用する accessor クラスの特殊化には、同じ名前と意味を持
つ多数のメンバータイプとメンバー関数があります。表 68 に一般的なタイプを示し、表 69 に一般的なメンバー関数を示します。
表 68. 非推奨のアクセサーの共通メンバータイプ
メンバーのタイプ

説明

value_type(AccessMode == access_mode::read) である場合、const DataTに等しく、それ以外は DataT に等しくなります。

referencevalue_type& と等価です。

const_reference

const DataT& と等価です。

表 69. 非推奨のアクセサーの共通メンバー関数
メンバー関数説明

size_t get_size() const noexcept

アクセサーがアクセスできるメモリー領域のサイズをバイト単位で返します。
AccessTarget が target::constant_buffer または target::host_buffer である場合、戻り値はベースとなるバッファー内の要素サイズになります。ただし、レンジ付きアクセサーではアクセサーのレン
ジ内の要素サイズとなります。
AccessTarget が target::local で あ る 場 合 、 戻 り 値 は workgroup ごとのアクセサーのローカルメモリー割り当てのサイズです (バイト単位)。

第 4 章 SYCL プログラミング・インターフェイス | 161

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

size_t get_count() const noexcept

アクセサーがアクセスできるメモリー領域の DataT 要素数を返します。
AccessTarget が target::constant_buffer または target::host_buffer である場合、戻り値はベースとなるバッファー内の要素数になります。ただし、レンジ付きアクセサーではアクセサーのレンジ内の要素数となります。
AccessTarget が target::local である場合、戻り値は work-group
ごとのアクセサーのローカルメモリー割り当ての要素数です。

range<Dimensions> get_range() const(Dimensions > 0) の場合にのみ利用できます。
このアクセサーがアクセスできる次元ごとの DataT の要素数を表す range オブジェクトを返します。
AccessTarget が target::constant_buffer または target::host_buffer である場合、戻り値はベースとなるバッファーのレンジになります。ただし、レンジ付きアクセサーではアクセサーの作成時に指定されたレンジとなります。
AccessTarget が target::local の場合、戻り値はアクセサーの作
成時に指定されたレンジです。

operator reference() const

AccessTarget が target::constant_buffer または target::host_buffer である場合、(Dimensions == 0) でのみ使用できます。
AccessTarget が target::local で あ る場 合、 (AccessMode ==access_mode::read_write && Dimensions == 0) でのみ使用できます。
アクセサーによってアクセスされる単一要素への参照を返します。

reference operator[](id<Dimensions> index) const

AccessTarget が target::constant_buffer または target::host_buffer である場合、(Dimensions > 0) でのみ使用できます。
AccessTarget が target::local で あ る場 合 、 (AccessMode ==access_mode::read_write && Dimensions > 0) でのみ使用できます。
index で指定される位置にある要素への参照を返します。これがレンジ付きアクセサーである場合、要素はアクセサーのオフセッ
トにインデックスを追加して決定されます。

162 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明__unspecified__ operator[](size_t index) const(Dimensions > 1) の場合にのみ利用できます。
このアクセサーを表す未定義の中間型インスタンスを返します。
次元は Dimensions-1 で、インデックス Dimensions が index に設定された暗黙の id を含みます。返される中間型は、このアクセサークラスによって定義され、そのタイプ (添字オペレーターを含む) に適した size_t パラメーターを受け取るすべての利用可能な
添字オペレーターを提供する必要があります。
レンジ付きアクセサーでは、返されるインスタンスの暗黙の id にはアクセサーのオフセットも含まれます。

reference operator[](size_t index) const

AccessTarget が target::constant_buffer または target::host_buffer である場合、(Dimensions == 1) でのみ使用できます。
AccessTarget が target::local で あ る場 合、 (AccessMode ==access_mode::read_write && Dimensions == 1) でのみ使用できます。
index で指定される位置にある要素への参照を返します。これがレンジ付きアクセサーである場合、要素はアクセサーのオフセッ
トにインデックスを追加して決定されます。

4.7.6.9.4.9. access_mode::atomic で特殊化されたアクセサー
accessor クラスは、ターゲット target::device およびアクセスモード access_mode::atomic で特殊化できます。この特殊化には、表70 で示されるように、ほかの target::device 特殊化に提供されるもの以外の追加メンバー関数があります。
表 70. accessor クラスの非推奨のアトミックメンバー関数
メンバー関数説明

operator atomic<DataT,(AccessMode == access_mode::atomic && Dimensions ==access::address_space::global_space>() const

0) の場合にのみ使用できます。
このアクセサーによってアクセスされる単一要素へのアトミック
アクセスを提供する、DataT タイプの atomic インスタンスを返します。

atomic<DataT, access::address_space::global_space>(AccessMode == access_mode::atomic && Dimensions > 0)

operator[]( id<Dimensions> index) constの場合にのみ使用できます。
index で指定されるインデックスで、アクセサーのバッファーに格納される要素へのアトミックアクセスを提供する、DataT タイプの atomic インスタンスを返します。
これがレンジ付きアクセサーである場合、戻り値の atomic イン
スタンスは、アクセサーのオフセットを index に追加することで位置が決定されるバッファー要素へのアクセスを提供します。

第 4 章 SYCL プログラミング・インターフェイス | 163

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

atomic<DataT, access::address_space::global_space>(AccessMode == access_mode::atomic && Dimensions ==operator[]( size_t index) const

1) の場合にのみ使用できます。
index で指定されるインデックスで、アクセサーのバッファーに格納される要素へのアトミックアクセスを提供する、DataT タイプの atomic インスタンスを返します。
これがレンジ付きアクセサーである場合、戻り値の atomic イン
スタンスは、アクセサーのオフセットを index に追加することで位置が決定されるバッファー要素へのアクセスを提供します。

4.7.6.10. ホストコードのバッファーアクセサー
host_accessor クラスは、コマンド外部のホストコードから buffer 内のデータへのアクセスを可能にします (このクラスを使用してホ
ストタスク内のバッファーにアクセスしてはなりません)。
accessor と同様に、host_accessor の次元数はベースとなるバッファーと一致しなければなりませんが、バッファーが 1 次元の場合は特別なケースがあります。この場合、アクセサーは 1 次元であっても、ゼロ次元であってもかまいません。
ゼロ次元のアクセサーはバッファーの最初の要素にのみアクセスできますが、1 次元バッファーはバッファー全体にアクセスできます。
host_accessor クラスは、access_mode::read、access_mode::write および access_mode::read_write アクセスモードをサポートします。

4.7.6.10.1. バッファー・ホスト・アクセサーのインターフェイス
host_accessor クラスの概要を以下に示します。一部のクラスタイプとメンバー関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については 4.7.6.12 節で説明します。表 79 にメンバータイプ、表 71 にコンストラクター、表 80 と表 72 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。アクセサータイプ間での有効な暗黙の変換については、4.7.6.10.3 節を参照してください。さらに、同じタイプのアクセサーは比較可能である必要があります。
1.

namespace sycl {2.

template <typename DataT,3.

int Dimensions = 1,

4.

access_mode AccessMode =5.

(std::is_const_v<DataT> ? access_mode::read

6.
7.
8.

: access_mode::read_write)>class host_accessor {public:9.

using value_type =// 読み取り専用アクセサーの const DataT、それ以外は DataT

10.

__value_type__;11.

using reference = value_type&;

12.

using const_reference = const DataT&;

13.

using iterator = __unspecified_iterator__ <value_type>;

14.

using const_iterator = __unspecified_iterator__ <const value_type>;

15.

using reverse_iterator = std::reverse_iterator <iterator>;

16.

using const_reverse_iterator = std::reverse_iterator<const_iterator>;

164 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
17.

using difference_type = typename std::iterator_traits<iterator>::difference_type;18.

using size_type = size_t;

19.
20.

host_accessor();

21.
22.

/* 次のときにのみ利用可能: (Dimensions == 0) */23.

template <typename AllocatorT>24.

host_accessor(buffer<DataT, 1, AllocatorT>& bufferRef,

25.

const property_list& propList = {});

26.
27.

/* 次のときにのみ利用可能: (Dimensions > 0) */28.

template <typename AllocatorT>29.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

30.

const property_list& propList = {});

31.
32.

/* 次のときにのみ利用可能: (Dimensions > 0) */33.

template <typename AllocatorT, typename TagT>

34.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef, TagT tag,

35.

const property_list& propList = {});

36.
37.

/* 次のときにのみ利用可能: (Dimensions > 0) */38.

template <typename AllocatorT>39.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

40.

range<Dimensions> accessRange, const property_list& propList = {});

41.
42.

/* 次のときにのみ利用可能: (Dimensions > 0) */43.

template <typename AllocatorT, typename TagT>

44.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

45.

range<Dimensions> accessRange, TagT tag,46.

const property_list& propList = {});

47.
48.

/* 次のときにのみ利用可能: (Dimensions > 0) */49.

template <typename AllocatorT>50.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

51.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

52.

const property_list& propList = {});

53.
54.

/* 次のときにのみ利用可能: (Dimensions > 0) */55.

template <typename AllocatorT, typename TagT>

56.

host_accessor(buffer<DataT, Dimensions, AllocatorT>& bufferRef,

57.

range<Dimensions> accessRange, id<Dimensions> accessOffset,

58.

TagT tag, const property_list& propList = {});

59.
60.

/* -- 共通インターフェイスのメンバー -- */

61.
62.

void swap(host_accessor& other);

63.
64.

size_type byte_size() const noexcept;

65.
66.

size_type size() const noexcept;

67.
68.

size_type max_size() const noexcept;

第 4 章 SYCL プログラミング・インターフェイス | 165

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
69.
70.

bool empty() const noexcept;

71.
72.

/* 次のときにのみ利用可能: (Dimensions > 0) */73.

range<Dimensions> get_range() const;

74.
75.

/* 次のときにのみ利用可能: (Dimensions > 0) */76.

id<Dimensions> get_offset() const;

77.
78.

/* 次のときにのみ利用可能: (Dimensions == 0) */79.

operator reference() const;

80.
81.

/* 次のときにのみ利用可能: (Dimensions == 0) */82.

const host_accessor& operator=(const value_type& other) const;

83.
84.

/* 次のときにのみ利用可能: (Dimensions == 0) */85.

const host_accessor& operator=(value_type&& other) const;

86.
87.

/* 次のときにのみ利用可能: (Dimensions > 0) */88.

reference operator[](id<Dimensions> index) const;

89.
90.

/* 次のときにのみ利用可能: (Dimensions > 1) */91.

__unspecified__ operator[](size_t index) const;

92.
93.

/* 次のときにのみ利用可能: (Dimensions == 1) */94.

reference operator[](size_t index) const;

95.
96.

std::add_pointer_t<value_type> get_pointer() const noexcept;

97.
98.

iterator begin() const noexcept;

99.
100.

iterator end() const noexcept;

101.
102.

const_iterator cbegin() const noexcept;

103.
104.

const_iterator cend() const noexcept;

105.
106.

reverse_iterator rbegin() const noexcept;

107.
108.

reverse_iterator rend() const noexcept;

109.
110.

const_reverse_iterator cbegin() const noexcept;

111.
112.

const_reverse_iterator crend() const noexcept;

113.

};

114.

} // namespace sycl

166 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 71. host_accessor クラスのコンストラクター
コンストラクター

説明

host_accessor()

次の事後条件を満たす空のアクセサーを作成します。

template <typename AllocatorT>
host_accessor(buffer<DataT, 1, AllocatorT>& bufferRef,
const property_list& propList = {})•(empty() == true)•

すべてのサイズ照会は 0 を返します。

•

get_pointer() の戻り値は未定義です。

•

メモリーアクセスを行うと未定義の動作となります。

(Dimensions == 0) の場合にのみ利用できます。
ホ ス ト 上 の buffer の 最 初 の 要 素 に 直 ち に ア ク セ ス す る
host_accessor を構築します。オプションの property_list は構
築されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
const property_list& propList = {})template <typename AllocatorT, typename TagT>
host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上の buffer に直ちにアクセスする host_accessor を構築します。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
(Dimensions > 0) の場合にのみ利用できます。
ホスト上の buffer に直ちにアクセスする host_accessor を構築します。tag は 4.7.6.10.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。

template <typename AllocatorT>
host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
range<Dimensions> accessRange,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上のバッファーに直ちにアクセスするレンジ付きアクセサーである host_accessor を作成します。レンジは、buffer の先
頭から始まります。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

template <typename AllocatorT, typename TagT>
host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
range<Dimensions> accessRange,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上のバッファーに直ちにアクセスするレンジ付きアクセサーである host_accessor を作成します。レンジは、buffer の先
頭から始まります。tag は 4.7.6.10.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange がいずれかの次元で bufferRef のレンジを超えると、errc::invalid エラーコードの例外をスローします。

第 4 章 SYCL プログラミング・インターフェイス | 167

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT>(Dimensions > 0) の場合にのみ利用できます。

host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
range<Dimensions> accessRange,
id<Dimensions> accessOffset,
const property_list& propList = {})ホスト上のバッファーに直ちにアクセスするレンジ付きアクセサーである host_accessor を作成します。レンジは buffer の先
頭からのオフセットから始まります。オプションの property_list
は、構築されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

template <typename AllocatorT, typename TagT>
host_accessor(
buffer<DataT, Dimensions, AllocatorT>& bufferRef,
range<Dimensions> accessRange,
id<Dimensions> accessOffset,
TagT tag, const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
ホスト上のバッファーに直ちにアクセスするレンジ付きアクセサーである host_accessor を作成します。レンジは buffer の先
頭からのオフセットから始まります。tag は 4.7.6.10.2 節で説明されるように、アクセサーのテンプレート引数を推定するために使用されます。オプションの property_list は作成されたアクセサーのプロパティーを提供します。
accessRange と accessOffset の合計とがいずれかの次元で
bufferRef のレンジを超えると、errc::invalid エラーコードの例外
をスローします。

表 72. host_accessor クラスのメンバー関数
メンバー関数説明

void swap(host_accessor& other);

現在のアクセサーの内容を other の内容とスワップします。

id<Dimensions> get_offset() const(Dimensions > 0) の場合にのみ利用できます。
これがレンジ付きアクセサーである場合、アクセサーの構築時に指定されたオフセットを返します。その他のアクセサーでは、デフォルトで構築された id<Dimensions>{} を返します。

const host_accessor& operator=(const value_type& other)
const

const host_accessor& operator=(value_type&& other)
const

Dimensions == 0 の場合にのみ利用できます。
アクセサーによってアクセスされる単一要素への参照を返します。
Dimensions == 0 の場合にのみ利用できます。
アクセサーによってアクセスされる単一要素への参照を返します。

4.7.6.10.2. バッファー・コマンド・アクセサーのデダクション・タグ
一部の host_accessor のコンストラクターは、テンプレート引数を推定する際に使用される TagT パラメーターを受け取ります。この
パラメーターの許容値は、表 73 にアクセスモードセサーターゲットとともに示します。

168 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 73. host_accessor の構築に使用可能なタグの列挙
タグ値

アクセスモード

read_write

access_mode::read_write

read_only

access_mode::read

write_only

access_mode::write

4.7.6.10.3. 読み取り専用バッファー・ホスト・アクセサーと暗黙の変換
表 74 は、読み取り専用アクセサーである host_accessor の特殊化を示します。ほかのすべてのテンプレート・パラメーターが同一である場合、これらの特殊化間では暗黙の変換が行われます。
表 74. 読み取り専用の host_accessor の特殊化
データタイプ

アクセスモード

const 修飾されていません

access_mode::read

const 修飾されています

access_mode::read

ほかのすべてのテンプレート・パラメーターが同一である場合、表 75 に示す読み取り/書き込み host_accessor タイプから、表 74 の読み取り専用アクセサーへ暗黙的に変換されます。
表 75. 読み取り/書き込みの host_accessor の特殊化
データタイプ

アクセスモード

const 修飾されていません

access_mode::read_write

4.7.6.11. ローカルアクセサー
local_accessor クラスは、デバイスのローカルメモリーを割り当て、SYCL カーネル関数からそのメモリーへのアクセスを提供します。
割り当てられたローカルメモリーは、work-group のすべての work-item 間で共有されます。実装では、複数の work-group が同時に実行されると、各 work-group は割り当てられたローカルメモリーの独立したコピーを受け取ります。
DataT タイプは任意の C++ タイプにできます。DataT が暗黙のライフタイム型 (C++ コア言語で定義) である場合、ローカルアクセ
サーは不確定値を持つタイプのオブジェクトを暗黙的に作成します。それ以外のタイプでは、ローカルアクセサーは初期化されていな
いメモリーを割り当てるだけで、アプリケーションがメモリー内にオブジェクトを構築する責任があります (例えば、プレースメント
new を呼び出して)。
ローカルアクセサーは、single_task または range パラメーターを受け取る単純な parallel_for によって呼び出される SYCL カーネ
ル関数内で使用してはなりません。それに反してカーネルをキューに送信すると、errc::kernel_argument エラーコードで同期例外をスローする必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 169

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.11.1. ローカルアクセサーのインターフェイス
local_accessor クラスの概要を以下に示します。一部のクラスタイプとメンバー関数は、ほかのアクセサーと同じ名前と意味を持つため、一般的なタイプと関数については 4.7.6.12 節で説明します。表 79 と表 76 にメンバータイプ、表 77 にコンストラクター、表 80 と表 78 にメンバー関数を示します。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。アクセサータイプ間での有効な暗黙の変換については、4.7.6.11.2 節を参照してください。さらに、同じタイプのアクセサーは比較可能である必要があります。
1.

namespace sycl {2.

template <typename DataT, int Dimensions = 1>

3.

class local_accessor {

4.
5.
6.

public:using value_type = // 読み取り専用アクセサーの const DataT、それ以外は DataT__value_type__;7.

using reference = value_type&;

8.

using const_reference = const DataT&;

9.

template <access::decorated IsDecorated>

10.
11.

using accessor_ptr =multi_ptr<value_type, access::address_space::local_space, IsDecorated>;

12.

using iterator = __unspecified_iterator__ <value_type>;

13.

using const_iterator = __unspecified_iterator__ <const value_type>;

14.

using reverse_iterator = std::reverse_iterator<iterator>;

15.

using const_reverse_iterator = std::reverse_iterator<const_iterator>;

16.

using difference_type = typename std::iterator_traits<iterator>::difference_type;17.

using size_type = size_t;

18.
19.

local_accessor();

20.
21.

/* 次のときにのみ利用可能: (Dimensions == 0) */22.

local_accessor(handler& commandGroupHandlerRef,

23.

const property_list& propList = {});

24.
25.

/* 次のときにのみ利用可能: (Dimensions > 0) */26.

local_accessor(range<Dimensions> allocationSize, handler& commandGroupHandlerRef,

27.

const property_list& propList = {});

28.
29.

/* -- 共通インターフェイスのメンバー -- */

30.
31.

void swap(accessor& other);

32.
33.

size_type byte_size() const noexcept;

34.
35.

size_type size() const noexcept;

36.
37.

size_type max_size() const noexcept;

38.
39.

bool empty() const noexcept;

40.
41.

range<Dimensions> get_range() const;

42.
43.

/* 次のときにのみ利用可能: (Dimensions == 0) */170 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
44.

operator reference() const;

45.
46.

/* 次のときにのみ利用可能: (Dimensions == 0) */47.

const local_accessor& operator=(const value_type& other) const;

48.
49.

/* 次のときにのみ利用可能: (Dimensions == 0) */50.

const local_accessor& operator=(value_type&& other) const;

51.
52.

/* 次のときにのみ利用可能: (Dimensions > 0) */53.

reference operator[](id<Dimensions> index) const;

54.
55.

/* 次のときにのみ利用可能: (Dimensions > 1) */56.

__unspecified__ operator[](size_t index) const;

57.
58.

/* 次のときにのみ利用可能: (Dimensions == 1) */59.

reference operator[](size_t index) const;

60.
61.

std::add_pointer_t<value_type> get_pointer() const noexcept;

62.
63.

template <access::decorated IsDecorated>

64.

accessor_ptr<IsDecorated> get_multi_ptr() const noexcept;

65.
66.

iterator begin() const noexcept;

67.
68.

iterator end() const noexcept;

69.
70.

const_iterator cbegin() const noexcept;

71.
72.

const_iterator cend() const noexcept;

73.
74.

reverse_iterator rbegin() const noexcept;

75.
76.

reverse_iterator rend() const noexcept;

77.
78.

const_reverse_iterator crbegin() const noexcept;

79.
80.

const_reverse_iterator crend() const noexcept;

81.

};

82.

} // namespace sycl

表 76. local_accessor クラスのメンバータイプ
メンバーのタイプ

説明

template <access::decorated IsDecorated> accessor_ptr

multi_ptr<value_type, access::address_space::local_space,
IsDecorated> と同じ。

第 4 章 SYCL プログラミング・インターフェイス | 171

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 77. local_accessor クラスのコンストラクター
コンストラクター

説明

local_accessor()

次の事後条件を満たす空のローカルアクセサーを作成します。

local_accessor(handler& commandGroupHandlerRef,
const property_list& propList = {})•(empty() == true)•

すべてのサイズ照会は 0 を返します。

•

get_pointer() と get_multi_ptr() の戻り値は未定義です。

•

メモリーアクセスを行うと未定義の動作となります。

(Dimensions == 0) の場合にのみ利用できます。
commandGroupHandlerRef に 関 連 付 け ら れ た キ ュ ー 上 のSYCL カーネル関数内の単一の DataT 要素のローカルメモリーにアクセスする local_accessor を構築します。 オプションのproperty_list は作成されたアクセサーのプロパティーを提供します。

local_accessor(range<Dimensions> allocationSize,
handler& commandGroupHandlerRef,
const property_list& propList = {})(Dimensions > 0) の場合にのみ利用できます。
commandGroupHandlerRef に 関 連 付 け ら れ た キ ュ ー 上 のSYCL カーネル関数内の DataT 配列要素のローカルメモリーにアクセスする local_accessor を構築します。配列内の要素数は、
allocationSize で定義されます。オプションの property_list は、構築されたアクセサーのプロパティーを提供します。

表 78. local_accessor クラスのメンバー関数
メンバー関数説明

void swap(local_accessor& other);

現在のアクセサーの内容を other の内容とスワップします。

template <access::decorated IsDecorated>

呼び出し work-group に対応するアクセサーのローカルメモリー

accessor_ptr<IsDecorated> get_multi_ptr() const noexcept 領域の先頭を指す multi_ptr を返します。アクセサーが空の場
合、戻り値は不定です。
この関数は、SYCL カーネル関数内からのみ呼び出すことができます。
const local_accessor& operator=(const value_type& other) Dimensions == 0 の場合にのみ利用できます。
const

アクセサーによってアクセスされる単一要素への参照を返します。
この関数は、コマンド内からのみ呼び出すことができます。

const local_accessor& operator=(value_type&& other)
const

Dimensions == 0 の場合にのみ利用できます。
アクセサーによってアクセスされる単一要素への参照を返します。
この関数は、コマンド内からのみ呼び出すことができます。

172 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.11.2. 読み取り専用ローカルアクセサーと暗黙の変換
local_accessor にはアクセスモードのテンプレート・パラメーターがないため、読み取り専用のローカルアクセサーを特殊化する唯一の方法は、const 修飾された DataT パラメーターを提供することです。const 修飾されない DataT パラメーターを使用する特殊化は、
読み取り/書き込みです。ほかのすべてのテンプレート・パラメーターが同一である場合、読み取り/書き込みの特殊化から読み取り専用の特殊化への暗黙の変換があります。

4.7.6.12. バッファーとローカルアクセサーの共通メンバー
accessor、host_accessor、および local_accessor クラスには、同じ名前と意味を持つメンバータイプとメンバー関数があります。表79 に一般的なタイプを示し、表 80 に一般的なメンバー関数を示します。
表 79. 共通バッファーとローカルアクセサーのメンバータイプ
メンバーのタイプ

説明

value_type

アクセサーが読み取り専用である場合、const DataT と等しく、それ以外は DataT と等しくなります。
アクセサーが読み取り専用と考えられる場合は、4.7.6.9.3 節、4.7.6.10.3 節および 4.7.6.11.2 節をご覧ください。

referencevalue_type& と等価です。

const_reference

const DataT& と等価です。

iteratorレンジ付きアクセスを提供するイテレーターです。アクセサーが読み取り専用である場合、書き込みはできません。ベースとなる
ポインターは、target::device で特殊化された accessor、および
local_accessor へのアドレス空間です。

const_iterator

レンジ付きアクセスを提供するイテレーターであり、書き込みできません。ベースとなるポインターは、target::device で特殊化された accessor、および local_accessor へのアドレス空間です。

reverse_iterator

iterator の方向を逆転するイテレーター・アダプターです。

const_reverse_iterator

const_iterator の方向を逆転するイテレーター・アダプターです。

difference_type

typename std::iterator_traits<iterator>::difference_type と同じです。

size_typesize_t と同じです。

第 4 章 SYCL プログラミング・インターフェイス | 173

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 80. 共通バッファーとローカルアクセサーのメンバー関数
メンバー関数説明

size_type byte_size() const noexcept

アクセサーがアクセスできるメモリー領域のサイズをバイト単位で返します。
バッファーアクセサーでは、これはベースとなるバッファーのサイズです。ただし、レンジ付きアクセサーの場合は、アクセサーのレ
ンジ内の要素サイズです。
ローカルアクセサーの場合、これは work-group ごとのアクセ
サーのローカルメモリー割り当てサイズです。

size_type size() const noexcept

アクセサーがアクセスできるメモリー領域の DataT 要素数を返します。
バッファーアクセサーでは、これはベースとなるバッファーの要素数です。ただし、レンジ付きアクセサーの場合は、アクセサーのレ
ンジ内の要素数です。
ローカルアクセサーの場合、これは work-group ごとのアクセ
サーのローカルメモリー割り当て要素数です。

size_type max_size() const noexcept

このタイプのアクセサーがアクセス可能な要素の最大数を返します。

bool empty() const noexcept(size() == 0) の場合 true を返します。

range<Dimensions> get_range() const(Dimensions > 0) の場合にのみ利用できます。
このアクセサーがアクセスできる次元ごとの DataT の要素数を表す range オブジェクトを返します。
バッファーアクセサーでは、これはベースとなるバッファーのレンジです。ただし、レンジ付きアクセサーの場合は、アクセサーの作
成時に指定されたレンジです。

operator reference() const(AccessMode != access_mode::atomic && Dimensions == 0)のときに accessor を利用できます。
(Dimensions == 0) のときに host_accessor と local_accessorを利用できます。
アクセサーによってアクセスされる単一要素への参照を返します。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

174 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

reference operator[](id<Dimensions> index) const(AccessMode != access_mode::atomic && Dimensions > 0)のときに accessor を利用できます。
(Dimensions > 0) のときに host_accessor と local_accessorを利用できます。
index で指定される位置にある要素への参照を返します。これがレンジ付きアクセサーである場合、要素はアクセサーのオフセッ
トにインデックスを追加して決定されます。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

__unspecified__ operator[](size_t index) const(Dimensions > 1) の場合にのみ利用できます。
このアクセサーを表す未定義の中間型インスタンスを返します。
次元は Dimensions-1 で、インデックス Dimensions が index に設定された暗黙の id を含みます。返される中間型は、このアクセサークラスによって定義され、そのタイプ (添字オペレーターを含む) に適した size_t パラメーターを受け取るすべての利用可能な
添字オペレーターを提供する必要があります。
レンジ付きアクセサーでは、返されるインスタンスの暗黙の id にはアクセサーのオフセットも含まれます。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

reference operator[](size_t index) const(AccessMode != access_mode::atomic && Dimensions == 1)のときに accessor を利用できます。
(Dimensions == 1) のときに host_accessor と local_accessorを利用できます。
index で指定される位置にある要素への参照を返します。これがレンジ付きアクセサーである場合、要素はアクセサーのオフセッ
トにインデックスを追加して決定されます。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

std::add_pointer_t<value_type> get_pointer() const
noexcept

このアクセサーのメモリーの先頭へのポインターを返します。
バッファーアクセサーの場合、レンジがバッファーの先頭から始
まらないレンジ付きアクセサーであっても、ベースとなるバッ
ファーの先頭へのポインターになります。
アクセサーが空の場合、戻り値は不定です。
accessor および local_accessor では、この関数はコマンド内からのみ呼び出し可能です。

第 4 章 SYCL プログラミング・インターフェイス | 175

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

iterator begin() const noexcept

アクセサーがアクセスする可能性があるメモリーの先頭の要素へのイテレーターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最初の要素へのイテレーターです。ただし、レンジ付きアクセサーの場
合は、アクセサーのレンジ内の最初の要素へのイテレーターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

iterator end() const noexcept

このアクセサーがアクセスできるメモリーの最後の要素の 1 つ先の要素へのイテレーターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最後の要素の 1 つ先の要素のイテレーターです。ただし、レンジ付きア
クセサーの場合は、アクセサーのレンジ内の最後の要素の 1 つ先の要素へのイテレーターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

const_iterator cbegin() const noexcept

アクセサーがアクセスする可能性があるメモリーの先頭の要素への定数イテレーターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最初の要素への定数イテレーターです。ただし、レンジ付きアクセサーの場合は、アクセサーのレンジ内の最初の要素への定数イテレー
ターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

const_iterator cend() const noexcept

このアクセサーがアクセスできるメモリーの最後の要素の 1 つ先の要素の定数イテレーターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最後の要素の 1 つ先の要素への定数イテレーターです。ただし、レンジ付きアクセサーの場合は、アクセサーのレンジ内の最後の要素の
1 つ先の要素への定数イテレーターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

176 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

メンバー関数説明

reverse_iterator rbegin() const noexcept

アクセサーがアクセスする可能性があるメモリーの最後の要素へのイテレーター・アダプターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最後の要素へのイテレーター・アダプターです。ただし、レンジ付きアクセサーの場合は、アクセサーのレンジ内の最後の要素へのイテ
レーター・アダプターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

reverse_iterator rend() const noexcept

このアクセサーがアクセスできるメモリーの最初の要素の 1 つ前の要素へのイテレーター・アダプターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最初の要素の 1 つ前の要素へのイテレーター・アダプターです。ただし、レンジ付きアクセサーの場合は、アクセサーのレンジ内の最初の要素の 1 つ前の要素へのイテレーター・アダプターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

const_reverse_iterator crbegin() const noexcept

アクセサーがアクセスする可能性があるメモリーの最後の要素への定数イテレーター・アダプターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最後の要素への定数イテレーター・アダプターです。ただし、レンジ付
きアクセサーの場合は、アクセサーのレンジ内の最後の要素への定数イテレーター・アダプターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

const_reverse_iterator crend() const noexcept

このアクセサーがアクセスできるメモリーの最初の要素の 1 つ前の要素への定数イテレーター・アダプターを返します。
バッファーアクセサーでは、これはベースとなるバッファーの最初の要素の 1 つ前の要素への定数イテレーター・アダプターです。ただし、レンジ付きアクセサーの場合は、アクセサーのレンジ
内の最初の要素の 1 つ前の要素への定数イテレーター・アダプ
ターです。
accessor および local_accessor では、この関数はコマンド内から呼び出し可能です。

4.7.6.13. 非サンプルイメージのアクセサー
非サンプルイメージのアクセサーを実装するクラスは、unsampled_image_accessor と host_unsampled_image_accessor です。
前者は、SYCL カーネル関数またはホストタスクからのアクセスを提供します。後者は、ホストタスク外のホストコードからのアクセスを提供します。

第 4 章 SYCL プログラミング・インターフェイス | 177

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
非サンプルイメージのアクセサーの次元は、アクセスを提供するベースとなるイメージの次元と一致しなければなりません。非サンプ
ルイメージのアクセサーは、 access_mode::read および access_mode::write アクセスモードのみをサポートします。 さらに、
host_unsampled_image_accessor クラスは、access_mode :: read_write をサポートします。
AccessTarget テンプレート・パラメーターは、unsampled_image_accessor の使い方を指定します。image_target::device はアクセサーを SYCL カーネル関数で使用することを示し、image_target::host_task はホストタスクで使用することを意味します。このテン
プレート・パラメーターを image_target::device にすると、ホストタスクから unsampled_image_accessor を使用するプログラムは
正しく構成されません。同様に、このテンプレート・パラメーターを image_target::host_task に指定し、SYCL カーネル関数から
unsampled_image_accessor を使用するプログラムも正しい形式ではありません。

4.7.6.13.1. 非サンプルイメージのアクセサー・インターフェイス
2 つの非サンプルイメージのアクセサークラスの概要を以下に示します。両方のクラスには、表 81 で示す同じ名前のメンバー関数があります。2 つのクラスのコンストラクターは、表 82 および表 83 に示します。両方のクラスには、表 84 で示す同じ名前のメンバー関
数もあります。
追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。アクセサータイプ間での有効な暗黙の変換については、4.7.6.13.3 節を参照してください。
同じタイプの 2 つの unsampled_image_accessor オブジェクトは、ホストコードと SYCL カーネル関数の両方で同一である必要があります。同じタイプの 2 つの host_unsampled_image_accessor オブジェクトは、ホストコードで同一である必要があります。
1.

namespace sycl {2.
3.

enum class image_target ： /* 未定義 */ {4.

device,5.

host_task

6.

};

7.
8.

template <typename DataT,

9.

int Dimensions,10.

access_mode AccessMode,

11.

image_target AccessTarget = image_target::device>

12.
13.
14.
15.

class unsampled_image_accessor {public:using value_type =// 読み取り専用アクセサーの const DataT、それ以外は DataT__value_type__;16.

using reference = value_type&;

17.

using const_reference = const DataT&;

18.
19.

template <typename AllocatorT>20.

unsampled_image_accessor(unsampled_image<Dimensions, AllocatorT>& imageRef,

21.

handler& commandGroupHandlerRef,

22.

const property_list& propList = {});

23.
24.

template <typename AllocatorT, typename TagT>

25.

unsampled_image_accessor(unsampled_image<Dimensions, AllocatorT>& imageRef,26.

handler& commandGroupHandlerRef, TagT tag,

27.

const property_list& propList = {});

28.
29.

/* -- 共通インターフェイスのメンバー -- */30.

178 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ31.

/* -- プロパティー・インターフェイスのメンバー -- */

32.
33.

size_t size() const noexcept;

34.
35.

/*:AccessMode == access_mode::read の場合にのみ利用可能

36.

Dimensions == 1 の場合 CoordT = int

37.

Dimensions == 2 の場合 CoordT = int2

38.

Dimensions == 4 の場合 CoordT = int4 */39.

template <typename CoordT>

40.

DataT read(const CoordT& coords) const noexcept;

41.
42.

/*:AccessMode == access_mode::write の場合にのみ利用可能

43.

Dimensions == 1 の場合 CoordT = int

44.

Dimensions == 2 の場合 CoordT = int2

45.

Dimensions == 3 の場合 CoordT = int4 */46.

template <typename CoordT>

47.

void write(const CoordT& coords, const DataT& color) const;

48.

};

49.
50.

template <typename DataT,

51.

int Dimensions,52.

access_mode AccessMode>

53.
54.
55.
56.

class host_unsampled_image_accessor {public:using value_type =// 読み取り専用アクセサーの const DataT、それ以外は DataT__value_type__;57.

using reference = value_type&;

58.

using const_reference = const DataT&;

59.
60.

template <typename AllocatorT>61.

host_unsampled_image_accessor(unsampled_image<Dimensions, AllocatorT>& imageRef,62.

const property_list& propList = {});

63.
64.

template <typename AllocatorT, typename TagT>

65.

host_unsampled_image_accessor(unsampled_image<Dimensions, AllocatorT>& imageRef,

66.

TagT tag, const property_list& propList = {});

67.
68.

/* -- 共通インターフェイスのメンバー -- */

69.
70.

/* -- プロパティー・インターフェイスのメンバー -- */

71.
72.

size_t size() const noexcept;

73.
74.

/*:AccessMode == access_mode::read の場合にのみ利用可能

75.

Dimensions == 1 の場合 CoordT = int

76.

Dimensions == 2 の場合 CoordT = int2

77.

Dimensions == 4 の場合 CoordT = int4 */78.

template <typename CoordT>

79.

DataT read(const CoordT& coords) const noexcept;

80.
81.

/*:AccessMode == access_mode::write の場合にのみ利用可能

82.

Dimensions == 1 の場合 CoordT = int

第 4 章 SYCL プログラミング・インターフェイス | 179

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
83.

Dimensions == 2 の場合 CoordT = int2

84.

Dimensions == 3 の場合 CoordT = int4 */85.

template <typename CoordT>

86.
87.

void write(const CoordT& coords, const DataT& color) const;
};

88.
89.

} // namespace sycl

表 81. unsampled イメージクラスのメンバータイプ
メンバーのタイプ

説明

value_type

アクセサーが読み取り専用である場合、const DataT と等しく、それ以外は DataT と等しくなります。
アクセサーが読み取り専用と考えられる場合は、4.7.6.13.3 節を参照してください。

referencevalue_type& と等価です。

const_reference

const DataT& と等価です。

表 82. unsampled_image_accessor クラスのコンストラクター
コンストラクター

説明

template <typename AllocatorT>commandGroupHandlerRef に関連付けられたキューのコマン

unsampled_image_accessor(

ド 内 の unsampled_image に ア ク セ ス す る unsampled_
unsampled_image<Dimensions, AllocatorT>& imageRef, image_accessor を構築します。オプションの property_list はhandler& commandGroupHandlerRef,
作成されたオブジェクトのプロパティーを提供します。
const property_list& propList = {})AccessTarget がimage_target::device で あ る 場 合 、

commandGroupHandlerRef に 関 連 付 け ら れ た デ バ イ ス にaspect::image がないときに、errc::feature_not_supported エ
ラーコードで例外をスローします。
template <typename AllocatorT, typename TagT>commandGroupHandlerRef に関連付けられたキューのコマン

unsampled_image_accessor(

ド 内 の unsampled_image に ア ク セ ス す る unsampled_

unsampled_image<Dimensions, AllocatorT>&
imageRef,

image_accessor を構築します。tag は、4.7.6.13.2 節で説明されるように、unsampled_image_accessor のテンプレート引数をhandler& commandGroupHandlerRef, TagT tag,

推定するために使用されます。オプションの property_list は作

const property_list& propList = {})成されたオブジェクトのプロパティーを提供します。
AccessTarget がimage_target::device で あ る 場 合 、

commandGroupHandlerRef に 関 連 付 け ら れ た デ バ イ ス にaspect::image がないときに、errc::feature_not_supported エ
ラーコードで例外をスローします。

180 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 83. host_unsampled_image_accessor クラスのコンストラクター
コンストラクター

説明

template <typename AllocatorT>

ホ ス ト 上 の unsampled_image に 直 ち に ア ク セ ス す る

host_unsampled_image_accessor(

host_unsampled_image_accessor を構築します。オプション

unsampled_image<Dimensions, AllocatorT>&
imageRef,の property_list は、構築されたオブジェクトのプロパティーを提供します。

const property_list& propList = {})template <typename AllocatorT, typename TagT>

ホスト上の unsampled_image に直ちにアクセスする host_

host_unsampled_image_accessor(

unsampled_image_accessor を構築します。tag は、4.7.6.13.2

unsampled_image<Dimensions, AllocatorT>&
imageRef,
TagT tag, const property_list& propList = {})節で説明されるように、host_unsampled_image_accessor のテンプレート引数を推定するために使用されます。オプションのproperty_list は作成されたオブジェクトのプロパティーを提供します。

表 84. unsampled イメージクラスのメンバー関数
メンバー関数説明

size_t size() const noexcept

このアクセサーがアクセスするベースとなる unsampled_imageの要素数を返します。

template <typename CoordT>(AccessMode == access_mode::read) の場合にのみ使用で

DataT read(const CoordT& coords) const

きます。
coords で指定される座標にある unsampled_image の要素を
読 み 取 っ て 返 し ま す 。 CoordT で 許 可 さ れ る タ イ プ は 、Dimensions == 1 では int、Dimensions == 2 では int2、そしてDimensions == 3 では int4 です。
unsampled_image_accessor では、この関数はコマンド内からのみ呼び出し可能です。

template <typename CoordT>(AccessMode == access_mode::write) の場合にのみ使用できvoid write(const CoordT& coords, const DataT& color)

ます。

const

color で指定される値を coords で指定される座標にあるイメー
ジ の 要 素 に 書 き 込 み ま す 。 CoordT で 許 可 さ れ る タ イ プ は 、Dimensions == 1 では int、Dimensions == 2 では int2、そしてDimensions == 3 では int4 です。
unsampled_image_accessor では、この関数はコマンド内からのみ呼び出し可能です。

4.7.6.13.2. 非サンプル・イメージ・アクセサーのデダクション・タグ
一部の unsampled_image_accessor のコンストラクターは、テンプレート引数を推定する際に使用される TagT パラメーターを受け取ります。このパラメーターの許容値は、表 85 にアクセスモードとアクセサーターゲットとともに示します。

第 4 章 SYCL プログラミング・インターフェイス | 181

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 85. unsampled_image_accessor の構築に使用可能なタグの列挙
タグ値

アクセスモード

アクセサーのターゲット

read_only

access_mode::read

image_target::device

write_only

access_mode::write

image_target::device

read_only_host_task

access_mode::read

image_target::host_task

write_only_host_task

access_mode::write

image_target::host_task

一部の host_unsampled_image_accessor コンストラクターも TagT パラメーターを受け入れます。このパラメーターの許容値は、
表 86 にアクセスモードとともに示します。
表 86. host_unsampled_image_accessor の構築に使用可能なタグの列挙
タグ値

アクセスモード

read_only

access_mode::read

write_only

access_mode::write

read_write

access_mode::read_write

4.7.6.13.3. 読み取り専用非サンプル・イメージ・アクセサーと暗黙の変換
access_mode::read で特殊化されるすべての非イメージアクセサーは、DataT が const 修飾されるかどうかにかかわらず読み取り専用です。ほかのすべてのテンプレート・パラメーターが同一である場合、const 修飾と const 修飾されない特殊化間では暗黙の変換が行われます。

4.7.6.14. サンプル・イメージ・アクセサー
サンプルイメージのアクセサーを実装するクラスには、sampled_image_accessor と host_sampled_image_accessor の 2 つがあります。前者は、SYCL カーネル関数またはホストタスクからのアクセスを提供します。後者は、ホストタスク外のホストコードからのア
クセスを提供します。
サンプルイメージのアクセサーの次元は、アクセスを提供するベースとなるイメージの次元と一致しなければなりません。サンプル・イ
メージ・アクセサーは常に読み取り専用です。
AccessTarget テンプレート・パラメーターは、sampled_image_accessor の使い方を指定します。image_target::device はアクセ
サーを SYCL カーネル関数で使用することを示し、image_target::host_task はホストタスクで使用することを意味します。このテンプ
レート・パラメーターを image_target::device にすると、ホストタスクから sampled_image_accessor を使用するプログラムは正しく構成され ません 。同様に、 このテンプレ ート・パラメー ターを image_target::host_task に指定し、 SYCL カー ネ ル関数 から
sampled_image_accessor を使用するプログラムも正しい形式ではありません。

4.7.6.14.1. サンプル・イメージ・アクセサーのインターフェイス
2 つのサンプルイメージのアクセサークラスの概要を以下に示します。両方のクラスには、表 87 で示す同じ名前のメンバータイプがあります。2 つのクラスのコンストラクターについては、表 88 と表 89 で説明します。両方のクラスには、表 90 で示す同じ名前のメンバー
関数もあります。

182 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ追加の共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 に示します。サンプル・アクセサー・タイプ間での有効な暗黙の変換については、4.7.6.14.3 節を参照してください。
同じタイプの 2 つの sampled_image_accessor オブジェクトは、ホストコードと SYCL カーネル関数の両方で同一である必要があります。同じタイプの 2 つの host_sampled_image_accessor オブジェクトは、ホストコードで同一である必要があります。
1.

namespace sycl {2.
3.

enum class image_target ： /* 未定義 */ {4.

device,5.
6.

host_task
};

7.
8.

template <typename DataT,

9.

int Dimensions,

10.
11.

image_target AccessTarget = image_target::device>class sampled_image_accessor {12.

public:13.

using value_type = const DataT;

14.

using reference = const DataT&;

15.

using const_reference = const DataT&;

16.
17.

template <typename AllocatorT>

18.

sampled_image_accessor(sampled_image<Dimensions, AllocatorT>& imageRef,

19.

handler& commandGroupHandlerRef,

20.

const property_list& propList = {});

21.
22.

template <typename AllocatorT, typename TagT>

23.

sampled_image_accessor(sampled_image<Dimensions, AllocatorT>& imageRef,

24.

handler& commandGroupHandlerRef, TagT tag,

25.

const property_list& propList = {});

26.
27.

/* -- 共通インターフェイスのメンバー -- */

28.
29.

/* -- プロパティー・インターフェイスのメンバー -- */

30.
31.

size_t size() const noexcept;

32.
33.

/* Dimensions == 1 の場合 CoordT = float

34.

Dimensions == 2 の場合 CoordT = float2

35.

Dimensions == 3 の場合 CoordT = float4 */36.

template <typename CoordT>

37.
38.

DataT read(const CoordT& coords) const noexcept;
};

39.
40.

template <typename DataT, int Dimensions>41.

class host_sampled_image_accessor{

42.

public:43.

using value_type = const DataT;

44.

using reference = const DataT&;

45.

using const_reference = const DataT&;

46.

第 4 章 SYCL プログラミング・インターフェイス | 183

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
47.

template <typename AllocatorT>48.

host_sampled_image_accessor(sampled_image<Dimensions, AllocatorT>& imageRef,49.

const property_list& propList = {});

50.

/* -- 共通インターフェイスのメンバー -- */

51.
52.

/* -- プロパティー・インターフェイスのメンバー -- */

53.
54.

size_t size() const noexcept;

55.
56.

/* Dimensions == 1 の場合 CoordT = float

57.

Dimensions == 2 の場合 CoordT = float2

58.

Dimensions == 3 の場合 CoordT = float4 */59.

template <typename CoordT>

60.
61.

DataT read(const CoordT& coords) const noexcept;
};

62.
63.

} // namespace sycl

表 87. サンプル・イメージ・クラスのメンバータイプ
メンバーのタイプ

説明

value_type

const DataT に等しい。

reference

const DataT& に等しい。

const_reference

const DataT& に等しい。

表 88. sampled_image_accessor クラスのコンストラクター
コンストラクター

説明

template <typename AllocatorT>commandGroupHandlerRef に関連付けられたキューのコマン

sampled_image_accessor(

ド 内 の sampled_image に ア ク セ ス す る sampled_image_

sampled_image<Dimensions, AllocatorT>& imageRef,

accessor を構築します。オプションの property_list は作成されhandler& commandGroupHandlerRef,

たオブジェクトのプロパティーを提供します。

const property_list& propList = {})AccessTarget が image_target::device である場合、
commandGroupHandlerRef に関連付けられたデバイスに
aspect::image がないときに、errc::feature_not_supported エ
ラーコードで例外をスローします。

184 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <typename AllocatorT, typename TagT>commandGroupHandlerRef に関連付けられたキューのコマン

sampled_image_accessor(

ド 内 の sampled_image に ア ク セ ス す る sampled_image_

sampled_image<Dimensions, AllocatorT>& imageRef,

accessor を構築します。tag は、4.7.6.14.2 節で説明されるよう

handler& commandGroupHandlerRef, TagT tag,に、sampled_image_accessor のテンプレート引数を推定する

const property_list& propList = {})ために使用されます。オプションの property_list は作成されたオブジェクトのプロパティーを提供します。
AccessTarget が image_target::device である場合、
commandGroupHandlerRef に関連付けられたデバイスに
aspect::image がないときに、errc::feature_not_supported エ
ラーコードで例外をスローします。

表 89. host_sampled_image_accessor クラスのコンストラクター
コンストラクター

説明

template <typename AllocatorT>

ホ ス ト 上 で 直 ち に sampled_image に ア ク セ ス す る host_

host_sampled_image_accessor(

sampled_image_accessor を 構 築 し ま す 。 オ プ シ ョ ン の

sampled_image<Dimensions, AllocatorT>& imageRef,property_list は作成されたオブジェクトのプロパティーを提供

const property_list& propList = {})します。

表 90. サンプル・イメージ・クラスのメンバー関数
メンバー関数説明

size_t size() const noexcept

このアクセサーがアクセスするベースとなる sampled_image の要素数を返します。

template <typename CoordT>

coords で指定される座標にある sampled_image のサンプル要

DataT read(const CoordT& coords) const

素 を 読 み 取 っ て 返 し ま す 。 CoordT で 許 可 さ れ る タ イ プ は 、Dimensions == 1 では float、Dimensions == 2 では float2、そして Dimensions == 3 では float4 です。
sampled_image_accessor では、この関数はコマンド内からのみ呼び出し可能です。

4.7.6.14.2. サンプル・イメージ・アクセサーのデダクション・タグ
一部の sampled_image_accessor のコンストラクターは、テンプレート引数を推定する際に使用される TagT パラメーターを受け取ります。このパラメーターの許容値は、表 91 にアクセサーターゲットとともに示します。
表 91. sampled_image_accessor の構築に使用可能なタグの列挙
タグ値

アクセサーのターゲット

read_only

image_target::device

read_only_host_task

image_target::host_task

第 4 章 SYCL プログラミング・インターフェイス | 185

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.6.14.3. 読み取り専用サンプル・イメージ・アクセサーと暗黙の変換
サンプリングされたイメージのすべての特殊化は、DataT が const 修飾されるかどうかにかかわらず読み取り専用です。ほかのすべてのテンプレート・パラメーターが同一である場合、const 修飾と const 修飾されない特殊化間では暗黙の変換が行われます。

4.7.7. アドレス空間クラス
SYCL には、グローバル、ローカル、定数、プライベート、ジェネリックの 5 つの異なるアドレス空間があります。SYCL ジェネリック実装
では、タイプはアドレス空間に影響されません。ただし、ユーザーがタイプのアドレス空間を明示的に保持することが求められる場合が
あります。
例:

• パフォーマンスのチューニングと汎用性のため。プラットフォームがジェネリック・アドレス空間表現をサポートする場合でも、パフォーマンスが犠牲になる可能性があります。ターゲット・コンパイラーを支援するため、ポインターがアドレス指定するアドレス
空間を追跡すると便利なことがあります。

• SYCL カーネルを SYCL バックエンド固有の関数とリンクする場合。この場合、ポインター・パラメーターのアドレス空間を指定する必要がある場合があります。
定義は実装依存であるため、アドレス空間とポインターを直接宣言することは推奨されません。ユーザーは、アドレス空間の境界と相互運用性を処理する multi_ptr クラスに従う必要があります。

4.7.7.1. 複数ポインタークラス
マルチポインター・クラスは、4.7.7.2 節で定義される明示的なポインタークラスの共通インターフェイスです。
場合によっては、タイプアドレス空間依存にしたいことがあります。これにより、データに関連付けられたアドレス空間に依存するジェネリック・プログラミングが可能になります。例えば、クラス内でポインターをラップする場合、ユーザーはクラスが初期化されるポイン
ターのアドレス空間に従ってクラスをテンプレート化する必要があります。これは、multi_ptr クラスを使用して移植可能な安定した方法で行えます。
multi_ptr クラスは、同じインターフェイスを 3 つの方法で公開します。access::decorated の値が access::decorated::no である場合、
イ ン タ ー フ ェ イ ス は ア ド レ ス 空 間 で 修 飾 さ れ て い な い ポ イ ン タ ー と 参 照 タ イ プ を 公 開 し ま す 。 access::decorated の 値 がaccess::decorated::yes である場合、インターフェイスはアドレス空間で修飾されるポインターと参照タイプを公開します。修飾は実装依存であるため、デバイス・コンパイラーの拡張機能に依存します。修飾されたタイプは、修飾されていないタイプと異なることがあります。SYCL バックエンドとの相互運用性のため、ユーザーは修飾されたバージョンで公開されるタイプに従う必要があります。
access::decorated の値が access::decorated::legacy の場合、SYCL 1.2.1 インターフェイスが公開されます。このインターフェイスは非推奨です。
テンプレート特性 remove_decoration とタイプエイリアス remove_decoration_t は、修飾されていないポインター、または参照修飾されたポインターから取得します。修飾されていないタイプでこのテンプレート特性を使用しても安全であり、同じタイプが返されます。
multi_ptr クラスに void タイプを使用できますが、その場合一部の機能が無効化されます。multi_ptr<void> は、reference またはconst_reference タイプ、アクセスオペレーター (operator*(), operator->())、算術オペレーター、または prefetch メンバー関数を提供しません。同じアドレス空間の multi_ptr から multi_ptr<void> への変換は許可され暗黙的に行われます。multi_ptr<void> から
同じアドレス空間の別の multi_ptr タイプへの変換も許可されますが、明示的でなければなりません。同様の規則が multi_ptr<const
void> にも適用されます。
multi_ptr クラスに提供されるインターフェイスの概要を次に示します。

186 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
1.

namespace sycl {2.

namespace access {3.
4.

enum class address_space : /* 未定義 */ {5.

global_space,6.

local_space,

7.

constant_space, // SYCL 2020 では非推奨

8.

private_space,

9.
10.

generic_space
};

11.
12.

enum class decorated : /* 未定義 */ {

13.

no,

14.

yes,

15.

legacy

16.

};

17.
18.

} // namespace access

19.
20.

template<typename T> struct remove_decoration {

21.
22.

using type = /* ... */;
};

23.
24.

template<typename T>

25.

using remove_decoration_t = remove_decoration<T>::type;

26.
27.

template <typename ElementType, access::address_space Space, access::decorated DecorateAddress>

28.

class multi_ptr {29.

public:30.

static constexpr bool is_decorated = DecorateAddress == access::decorated::yes;

31.

static constexpr access::address_space address_space = Space;

32.
33.

using value_type = ElementType;34.

using pointer = std::conditional_t<is_decorated, __unspecified__*,35.

std::add_pointer_t<value_type>>;36.

using reference = std::conditional_t<is_decorated, __unspecified__&,37.

std::add_lvalue_reference_t<value_type>>;38.

using iterator_category = std::random_access_iterator_tag;

39.

using difference_type = std::ptrdiff_t;

40.
41.

static_assert(std::is_same_v<remove_decoration_t<pointer>, std::add_pointer_t< value_type>>);42.

static_assert(std::is_same_v<remove_decoration_t<reference>,
std::add_lvalue_reference_t<value_type>>);43.

// レガシーには異なるインターフェイスがあります44.

static_assert(DecorateAddress != access::decorated::legacy);

45.
46.

// コンストラクター

47.

multi_ptr();48.

multi_ptr(const multi_ptr&);49.

multi_ptr(multi_ptr&&);50.

explicit multi_ptr(typename multi_ptr<ElementType, Space, access::decorated::yes>::pointer);

51.

multi_ptr(std::nullptr_t);

第 4 章 SYCL プログラミング・インターフェイス | 187

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ52.
53.

// Space == global_space または generic_space の場合に利用可能

54.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder>55.

multi_ptr(accessor<value_type, Dimensions, Mode, target::device, IsPlaceholder>);

56.
57.

// Space == local_space または generic_space の場合に利用可能

58.

template <int Dimensions>59.

multi_ptr(local_accessor<ElementType, Dimensions>)

60.
61.

// 非推奨62.

// Space == local_space または generic_space の場合に利用可能

63.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder>64.

multi_ptr(accessor<value_type, Dimensions, Mode, target::local, IsPlaceholder>);

65.
66.

// 割り当てとアクセスオペレーター

67.

multi_ptr& operator=(const multi_ptr&);

68.

multi_ptr& operator=(multi_ptr&&);69.

multi_ptr& operator=(std::nullptr_t);

70.
71.

// Space == address_space::generic_space72.

// および AS != access::address_space::constant_space の場合に利用可能

73.

template<access::address_space AS, access::decorated IsDecorated>

74.

multi_ptr& operator=(const multi_ptr<value_type, AS, IsDecorated>&);75.

// Space == address_space::generic_space76.

// および AS != access::address_space::constant_space の場合に利用可能

77.

template<access::address_space AS, access::decorated IsDecorated>

78.

multi_ptr& operator=(multi_ptr<value_type, AS, IsDecorated>&&);

79.
80.

reference operator[] (std::ptrdiff_t) const;

81.
82.

reference operator*() const;

83.

pointer operator->() const;

84.
85.

pointer get() const;86.

std::add_pointer_t<value_type> get_raw() const;

87.

__unspecified__* get_decorated() const;

88.
89.

// ベースとなるポインタータイプへの変換

90.

// 非推奨。代わりに get() を使用します91.

operator pointer() const;

92.
93.

// Space == address_space::generic_space の場合に利用可能

94.

// private_ptr へキャスト

95.

explicit operator multi_ptr<value_type, access::address_space::private_space,

96.

DecorateAddress>();97.

// Space == address_space::generic_space の場合に利用可能

98.

// private_ptr へキャスト

99.

explicit

100.

operator multi_ptr<const value_type, access::address_space::private_space,101.

DecorateAddress>() const;

102.

// Space == address_space::generic_space の場合に利用可能

103.

// global_ptr へキャスト

188 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
104.

explicit operator multi_ptr<value_type, access::address_space::global_space,

105.

DecorateAddress>();106.

// Space == address_space::generic_space の場合に利用可能

107.

// global_ptr へキャスト

108.

explicit

109.

operator multi_ptr<const value_type, access::address_space::global_space,

110.

DecorateAddress>() const;

111.

// Space == address_space::generic_space の場合に利用可能

112.

// local_ptr へキャスト

113.

explicit operator multi_ptr<value_type, access::address_space::local_space,

114.

DecorateAddress>();115.

// Space == address_space::generic_space の場合に利用可能

116.

// local_ptr へキャスト

117.

explicit

118.

operator multi_ptr<const value_type, access::address_space::local_space,119.

DecorateAddress>() const;

120.
121.

// multi_ptr<void> への暗黙の変換。

122.

// value_type が const 修飾されていない場合にのみ利用可能。

123.

template<access::decorated DecorateAddress2>

124.

operator multi_ptr<void, Space, DecorateAddress2>() const;

125.
126.

// multi_ptr<const void> への暗黙の変換。

127.

// value_type が const 修飾されている場合にのみ利用可能。

128.

template<access::decorated DecorateAddress2>

129.

operator multi_ptr<const void, Space, DecorateAddress2>() const;

130.
131.

// multi_ptr<const value_type, Space> への暗黙の変換。

132.

template<access::decorated DecorateAddress2>

133.

operator multi_ptr<const value_type, Space, DecorateAddress2>() const;

134.
135.

// 修飾されていない multi_ptr バージョンへの暗黙の変換。

136.

// is_decorated が true の場合にのみ利用可能。

137.

operator multi_ptr<value_type, Space, access::decorated::no>() const;

138.
139.

// 修飾された multi_ptr バージョンへの暗黙の変換。

140.

// is_decorated が false の場合にのみ利用可能。

141.

operator multi_ptr<value_type, Space, access::decorated::yes>() const;

142.
143.

void prefetch(size_t NumElements) const;

144.
145.

// 算術オペレーター

146.

friend multi_ptr& operator++(multi_ptr& mp) { /* ... */ }147.

friend multi_ptr operator++(multi_ptr& mp, int) { /* ... */ }148.

friend multi_ptr& operator--(multi_ptr& mp) { /* ... */ }149.

friend multi_ptr operator--(multi_ptr& mp, int) { /* ... */ }150.

friend multi_ptr& operator+=(multi_ptr& lhs, difference_type r) { /* ... */ }151.

friend multi_ptr& operator-=(multi_ptr& lhs, difference_type r) { /* ... */ }152.

friend multi_ptr operator+(const multi_ptr& lhs, difference_type r) { /* ... */ }153.

friend multi_ptr operator-(const multi_ptr& lhs, difference_type r) { /* ... */ }154.

friend reference operator*(const multi_ptr& lhs) { /* ... */

}

155.

第 4 章 SYCL プログラミング・インターフェイス | 189

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
156.

friend bool operator==(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }157.

friend bool operator!=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }158.

friend bool operator<(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }159.

friend bool operator>(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }160.

friend bool operator<=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }161.

friend bool operator>=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }

162.
163.

friend bool operator==(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }164.

friend bool operator!=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }165.

friend bool operator<(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }166.

friend bool operator>(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }167.

friend bool operator<=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }168.

friend bool operator>=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }

169.
170.

friend bool operator==(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }171.

friend bool operator!=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }172.

friend bool operator<(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }173.

friend bool operator>(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }174.

friend bool operator<=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }175.

friend bool operator>=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }

176.
177.

};

178.
179.

// void および const void の multi_ptr の特殊化

180.

// VoidType は void または const void のいずれかです181.

template <access::address_space Space, access::decorated DecorateAddress>

182.

class multi_ptr<VoidType, Space, DecorateAddress> {183.

public:184.

static constexpr bool is_decorated = DecorateAddress == access::decorated::yes;

185.

static constexpr access::address_space address_space = Space;

186.
187.

using value_type = VoidType;188.

using pointer = std::conditional_t<is_decorated, __unspecified__ value_type*,

189.
190.

std::add_pointer_t<value_type>>;using difference_type = std::ptrdiff_t;

191.
192.

static_assert(std::is_same_v<remove_decoration_t<pointer>, std::add_pointer_t< value_type>>);193.

// レガシーには異なるインターフェイスがあります194.

static_assert(DecorateAddress != access::decorated::legacy);

195.
196.

// コンストラクター

197.

multi_ptr();

198.

multi_ptr(const multi_ptr&);

199.

multi_ptr(multi_ptr&&);200.

explicit multi_ptr(typename multi_ptr<VoidType, Space, success::decorated::yes>::pointer);

201.

multi_ptr(std::nullptr_t);

202.
203.

// Space == global_space の場合にのみ

204.

template <typename ElementType, int Dimensions, access_mode Mode,

205.
206.
207.

access::placeholder IsPlaceholder>multi_ptr(accessor<ElementType, Dimensions, Mode,target::device, IsPlaceholder>);

190 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
208.
209.

// Space == local_space の場合にのみ

210.

template <typename ElementType, int Dimensions>211.

multi_ptr(local_accessor<ElementType, Dimensions>);

212.
213.

// 非推奨214.

// Space == local_space の場合にのみ

215.

template <typename ElementType, int Dimensions, access_mode Mode,

216.
217.

access::placeholder IsPlaceholder>multi_ptr(accessor<ElementType, Dimensions, Mode, target::local,

218.

IsPlaceholder>);

219.
220.

// 割り当て操作

221.

multi_ptr& operator=(const multi_ptr&);222.

multi_ptr& operator=(multi_ptr&&);223.

multi_ptr& operator=(std::nullptr_t);

224.
225.

pointer get() const;

226.
227.

// ベースとなるポインタータイプへの変換

228.

explicit operator pointer() const;

229.
230.

// multi_ptr<ElementType> への明示的な変換

231.

// VoidType が const の場合、ElementType も同様です232.

template <typename ElementType>233.

explicit operator multi_ptr<ElementType, Space, DecorateAddress>() const;

234.
235.

// 修飾されていない multi_ptr バージョンへの暗黙の変換。

236.

// is_decorated が true の場合にのみ利用可能。

237.

operator multi_ptr<value_type, Space, access::decorated::no>() const;

238.
239.

// 修飾された multi_ptr バージョンへの暗黙の変換。

240.

// is_decorated が false の場合にのみ利用可能。

241.

operator multi_ptr<value_type, Space, access::decorated::yes>() const;

242.
243.

// multi_ptr<const void, Space> への暗黙の変換

244.

operator multi_ptr<const void, Space, DecorateAddress>() const;

245.
246.

friend bool operator==(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }247.

friend bool operator!=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }248.

friend bool operator<(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }249.

friend bool operator>(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }250.

friend bool operator<=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }251.

friend bool operator>=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }

252.
253.

friend bool operator==(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }254.

friend bool operator!=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }255.

friend bool operator<(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }256.

friend bool operator>(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }257.

friend bool operator<=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }258.

friend bool operator>=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }259.

第 4 章 SYCL プログラミング・インターフェイス | 191

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ260.

friend bool operator==(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }261.

friend bool operator!=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }262.

friend bool operator<(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }263.

friend bool operator>(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }264.

friend bool operator<=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }265.

friend bool operator>=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }

266.
267.

};

268.
269.

// 非推奨。代わりに address_space_cast を使用します270.

template <typename ElementType, access::address_space Space, access::decorated DecorateAddress>271.

multi_ptr<ElementType, Space, DecorateAddress> make_ptr(ElementType*);

272.
273.

template <access::address_space Space, access::decorated DecorateAddress,

274.
275.

typename ElementType>multi_ptr<ElementType, Space, DecorateAddress> address_space_cast(ElementType*);

276.
277.

// デダクション・ガイド

278.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder,

279.
280.

class T>
multi_ptr(

281.

accessor<T, Dimensions, Mode, target::device, IsPlaceholder>)

282.
283.

-> multi_ptr<T, access::address_space::global_space>;
template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder,

284.
285.

class T>
multi_ptr(local_accessor<T, Dimensions>)286.

-> multi_ptr<T, access::address_space::local_space>;

287.
288.

} // namespace sycl

表 92. SYCL multi_ptr クラス・テンプレートのコンストラクター
コンストラクター

説明multi_ptr()

デフォルト・コンストラクター。

multi_ptr(const multi_ptr&)

コピー・コンストラクター。

multi_ptr(multi_ptr&&)

ムーブ・コンストラクター。

explicit multi_ptr(multi_ptr<ElementType, Space,

修飾されたポインターを引数として受け取るコンストラクター。

yes>::pointer)
multi_ptr(std::nullptr_t)

192 | 第 4 章 SYCL プログラミング・インターフェイス

nullptr からのコンストラクター。

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

コンストラクター

説明

template <int Dimensions, access_mode Mode,

次のときにのみ利用可能:

access::placeholder IsPlaceholder>multi_ptr(accessor<ElementType, Dimensions, Mode,target::device, IsPlaceholder>);Space == access::address_space::global_space || Space ==access::address_space::generic_space の場合。
target::device アクセサーから multi_ptr を構築します。
このコンストラクターは、コマンド内からのみ呼び出すことができます。

template <int Dimensions>multi_ptr(local_accessor<ElementType, Dimensions>)

次のときにのみ利用可能:
Space == access::address_space::global_space || Space ==access::address_space::generic_space の場合。
local_accessor から multi_ptr を構築します。
このコンストラクターは、コマンド内からのみ呼び出すことができます。

template <int Dimensions, access_mode Mode,SYCL 2020 では非推奨です。代わりに local_accessor でオー

access::placeholder IsPlaceholder>

バーロードします。

multi_ptr(accessor<ElementType, Dimensions, Mode,target::local, IsPlaceholder>);

次のときにのみ利用可能:
Space == access::address_space::global_space || Space ==access::address_space::generic_space の場合。
target::local アクセサーから multi_ptr を構築します。
このコンストラクターは、コマンド内からのみ呼び出すことができます。

template <typename ElementType, access::address_space SYCL 2020 では非推奨です。代わりに address_space_cast をSpace, access::decorated DecorateAddress>
multi_ptr<ElementType, Space, DecorateAddress>
make_ptr(ElementType* pointer)

使用します。
pointer 引数のアドレス空間に応じて multi_ptr インスタンスを作成するグローバル関数。
実装は、pointer の実行時の値が Space と互換性がない場合
nullptr を返す必要があり、推測されるアドレス空間が Space と互換性がない場合はコンパイル時に診断を発行する必要があります。

template <access::address_space, Space,Space と DecoratedAddress テンプレート引数を介して指定さaccess::decorated DecorateAddress, typename

れたアドレス空間と修飾を使用して pointer から multi_ptr イン

ElementType>

スタンスを作成するグローバル関数。

multi_ptr<ElementType, Space, DecorateAddress>
address_space_cast(ElementType* pointer)

pointer の実行時の値が Space と互換性がない場合、実装はnullptr を返し、pointer の推測アドレス空間が Space と互換性がない場合は、コンパイル時に診断を生成する必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 193

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 93. multi_ptr クラスのオペレーター
オペレーター説明

multi_ptr& operator=(const multi_ptr&)

コピー代入オペレーター。

multi_ptr& operator=(multi_ptr&&)

ムーブ代入オペレーター。

multi_ptr& operator=(std::nullptr_t)

nullptr を multi_ptr に割り当て。

template<access::address_space AS, access::decorated

次のときにのみ利用可能:

IsDecorated>Space == access::address_space::gener ic_space && AS !=multi_ptr& operator=(const multi_ptr<value_type, AS,
IsDecorated>&)access::address_space::constant_space の場合。
左側の multi_ptr の値を generic_ptr に割り当て。

template<access::address_space AS, access::decorated

次のときにのみ利用可能:

IsDecorated>Space == access::address_space::gener ic_space && AS !=multi_ptr& operator=(multi_ptr<value_type, AS,
IsDecorated>&&reference operator[] (std::ptrdoff_t i) const

access::ad dress_space::constant_space の場合。
左側の multi_ptr の値を generic_ptr に移動。
次のときにのみ利用可能:!std::is_void<value_type>::value の場合。
i 番目のポインター値を返します。i は負の場合もあります。

pointer operator→() const

次のときにのみ利用可能:!std::is_void<value_type>::value の場合。
ベースとなるポインター値を返します。

reference operator*() const

次のときにのみ利用可能:!std::is_void<value_type>::value の場合。
指示された値への参照を返します。

operator pointer() const

ベースとなるポインター型への暗黙の変換。
非推奨: メンバー関数 get を代わりに使用します。

template <access::decorated IsDecorated>
explicit operator multi_ptr<value_type,access::address_space::private_space, IsDecorated>()const

template <access::decorated IsDecorated>
explicit operator multi_ptr<const value_type,access::address_space::private_space, IsDecorated>()const

194 | 第 4 章 SYCL プログラミング・インターフェイス

次のときにのみ利用可能:
Space == access::address_space::generic_space の場合。
generic_ptr から private_ptr への変換。ポインターがグローバ
ルアドレス空間をアドレス指定しない場合、結果は未定義です。
次のときにのみ利用可能:
Space == access::address_space::generic_space の場合。
generic_ptr から private_ptr への変換。ポインターがグローバ
ルアドレス空間をアドレス指定しない場合、結果は未定義です。

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

オペレーター

説明

template <access::decorated IsDecorated>

次のときにのみ利用可能:

explicit operator multi_ptr<value_type,access::address_space::global_space, IsDecorated>() const

Space == access::address_space::generic_space の場合。
generic_ptr から global_ptr への変換。ポインターがローカルア
ドレス空間をアドレス指定しない場合、結果は未定義です。

template <access::decorated IsDecorated>
explicit operator multi_ptr<const value_type,access::address_space::global_space, IsDecorated>() const

次のときにのみ利用可能:
Space == access::address_space::generic_space の場合。
generic_ptr から global_ptr への変換。ポインターがローカルア
ドレス空間をアドレス指定しない場合、結果は未定義です。

template <access::decorated IsDecorated>

次のときにのみ利用可能:

explicit operator multi_ptr<value_type,Space == access::address_space::generic_space の場合。

access::address_space::local_space, IsDecorated>() const

generic_ptr から local_ptr への変換。ポインターがローカルアド
レス空間をアドレス指定しない場合、結果は未定義です。

template <access::decorated IsDecorated>
explicit operator multi_ptr<const value_type,access::address_space:: local _space, IsDecorated>() const

次のときにのみ利用可能:
Space == access::address_space::generic_space の場合。
generic_ptr から local_ptr への変換。ポインターがローカルア
ドレス空間をアドレス指定しない場合、結果は未定義です。

template <access::decorated IsDecorated>
operator multi_ptr<const void, Space, IsDecorated>()const

次のときにのみ利用可能:!std::is_void<value_type>::value &&
std::is_const<value_type>::value の場合。
const void タイプの multi_ptr への暗黙の変換。

template <access::decorated IsDecorated>

const value_type タイプの multi_ptr への暗黙の変換。

operator multi_ptr<const value_type, Space,
IsDecorated>() const
operator multi_ptr<const value_type, Space,

次のときにのみ利用可能:

access::decorated::no>() const

is_decorated == true の場合。
修飾されたポインターや参照を持たない同等の multi_ptr オブ
ジェクトへの暗黙の変換。

operator multi_ptr<const value_type, Space,

次のときにのみ利用可能:

access::decorated::yes>() const

is_decorated == false の場合。
修飾されたポインターや参照を持つ同等の multi_ptr オブジェク
トへの暗黙の変換。

第 4 章 SYCL プログラミング・インターフェイス | 195

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
表 94. multi_ptr クラスのメンバー関数
メンバー関数説明

pointer get() const

ベースとなるポインターを返します。ポインターが修飾されているかどうかは、DecorateAddress の値によって異なります。

__unspecified__* get_decorated() const

アドレス指定するアドレス空間で修飾されたベースとなるポイン
ターを返します。サポートには、実装で定義されるデバイス・コン
パイラー拡張が含まれることに注意してください。

std::add_pointer_t<value_type> get_raw() const

常に修飾されていないベースとなるポインターを返します。

void prefetch(size_t NumElements) const

次のときにのみ利用可能:
Space == access::address_space::global_space の場合。
NumElements で指定される要素数をグローバル・メモリー・キャッシュにプリフェッチします。この操作は実装定義の最適化であり、SYCL カーネル関数の機能的な動作には影響しません。

表 95. multi_ptr クラスの隠匿されたフレンド関数
隠匿されたフレンド関数

説明

reference operator*(const multi_ptr& mp)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp の value_type への参照を返すオペレーター。

multi_ptr& operator++(multi_ptr& mp)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を 1 つインクリメントして mp を返します。

multi_ptr operator++(multi_ptr& mp, int)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を 1 インクリメントし、元の mp 値の新しい multi_ptr を返します。

multi_ptr& operator--(multi_ptr& mp)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を 1 つデクリメントして mp を返します。

multi_ptr operator--(multi_ptr& mp, int)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を 1 デクリメントし、元の mp 値の新しい multi_ptr を返します。

196 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ隠匿されたフレンド関数

説明

multi_ptr& operator+=(multi_ptr& lhs, difference_type r)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を r だけ前方移動して lhs を返します。

multi_ptr& operator-=(multi_ptr& lhs, difference_type r)

次のときにのみ利用可能:!std::is_void<ElementType>::value の場合。
mp を r だけ後方移動して lhs を返します。

multi_ptr operator+(const multi_ptr& lhs, difference_type

次のときにのみ利用可能:r)!std::is_void<ElementType>::value の場合。
lhs と比べて r だけ前方移動する新しい multi_ptr を作成します。

multi_ptr operator-(const multi_ptr& lhs, difference_type

次のときにのみ利用可能:r)!std::is_void<ElementType>::value の場合。
lhs と比べて r だけ後方移動する新しい multi_ptr を作成します。

bool operator==(const multi_ptr& lhs, const multi_ptr&

multi_ptr クラスの比較オペレーター ==。

rhs)bool operator!=(const multi_ptr& lhs, const multi_ptr& rhs) multi_ptr クラスの比較オペレーター !=。
bool operator<(const multi_ptr& lhs, const multi_ptr& rhs) multi_ptr クラスの比較オペレーター <。
bool operator>(const multi_ptr& lhs, const multi_ptr& rhs) multi_ptr クラスの比較オペレーター >。
bool operator<=(const multi_ptr& lhs, const multi_ptr&

multi_ptr クラスの比較オペレーター <=。

rhs)bool operator>=(const multi_ptr& lhs, const multi_ptr&

multi_ptr クラスの比較オペレーター >=。

rhs)bool operator==(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター ==。

bool operator!=(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター !=。

bool operator<(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター <。

bool operator>(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター >。

bool operator<=(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター <=。

bool operator>=(const multi_ptr& lhs, std::nullptr_t)

multi_ptr クラスの比較オペレーター >=。

bool operator==(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター ==。

第 4 章 SYCL プログラミング・インターフェイス | 197

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ隠匿されたフレンド関数

説明bool operator!=(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター !=。

bool operator<(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター <。

bool operator>(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター >。

bool operator<=(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター <=。

bool operator>=(std::nullptr_t, const multi_ptr& rhs)

multi_ptr クラスの比較オペレーター >=。

以下は、multi_ptr クラスに提供される SYCL 1.2.1 のレガシー・インターフェイスの概要です。
このレガシークラスは、非推奨の address_space::constant_space アドレス空間をサポートします。これは、定数メモリーへのポイン
ターを表現するために使用できます。定数メモリーへのポインターには実装定義のアドレス空間があるため、各実装はポインターを汎用アドレスポインターに割り当てることを許可するか定義できます。
1.

namespace sycl {2.
3.

// 1.2.1 から継承されたレガシー・インターフェイス。

4.

// 非推奨5.

template <typename ElementType, access::address_space Space>

6.

class [[deprecated]] multi_ptr<ElementType, Space, access::decorated::legacy> {7.

public:8.

using element_type = ElementType;9.

using difference_type = std::ptrdiff_t;

10.
11.

// OpenCL C 関数の SYCL/OpenCL 相互運用性タイプに対応する

12.

// 実装定義のポインターおよび参照タイプ

13.

using pointer_t = multi_ptr<ElementType, Space, access::decorated::yes>::pointer;

14.

using const_pointer_t = multi_ptr<const ElementType, Space, access::decorated::yes>::pointer;15.

using reference_t = multi_ptr<ElementType, Space, access::decorated::yes>::reference;

16.

using const_reference_t = multi_ptr<const ElementType, Space, access::decorated::yes>::reference;

17.
18.

static constexpr access::address_space address_space = Space;

19.
20.

// コンストラクター

21.

multi_ptr();

22.

multi_ptr(const multi_ptr&);

23.

multi_ptr(multi_ptr&&);24.

multi_ptr(pointer_t);25.

multi_ptr(ElementType*);26.

multi_ptr(std::nullptr_t);27.

~multi_ptr(); 28

28.
29.

// 割り当てとアクセスオペレーター

30.

multi_ptr& operator=(const multi_ptr&);31.

multi_ptr& operator=(multi_ptr&&);32.

multi_ptr& operator=(pointer_t);

198 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
33.

multi_ptr& operator=(ElementType*);34.

multi_ptr& operator=(std::nullptr_t);

35.

friend ElementType& operator*(const multi_ptr& mp) { /* ... */ }36.

ElementType* operator->() const; 37

37.
38.

// Space == global_space の場合にのみ

39.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder>40.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::device, IsPlaceholder>);

41.
42.

// Space == local_space の場合にのみ

43.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder>44.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::local, IsPlaceholder>);

45.
46.

// Space == constant_space の場合にのみ

47.

template <int Dimensions, access_mode Mode, access::placeholder IsPlaceholder>48.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::constant_buffer, IsPlaceholder>);

49.
50.

// ベースとなる OpenCL の C ポインターを返します51.

pointer_t get() const;

52.
53.

// ベースとなるポインタータイプへの暗黙的変換

54.

operator ElementType*() const;

55.
56.

// multi_ptr<void> への暗黙の変換

57.

// ElementType が const 修飾されていない場合にのみ利用可能

58.

operator multi_ptr<void, Space, access::decorated::legacy>() const;

59.
60.

// multi_ptr<const void> への暗黙の変換

61.

// ElementType が const 修飾されている場合にのみ利用可能

62.

operator multi_ptr<const void, Space, access::decorated::legacy>() const;

63.
64.

// multi_ptr<const ElementType, Space> への暗黙の変換

65.

operator multi_ptr<const ElementType, Space, access::decorated::legacy>();

66.
67.

// 算術オペレーター

68.

friend multi_ptr& operator++(multi_ptr& mp) { /* ... */ }69.

friend multi_ptr operator++(multi_ptr& mp, int) { /* ... */ }70.

friend multi_ptr& operator--(multi_ptr& mp) { /* ... */ }71.

friend multi_ptr operator--(multi_ptr& mp, int) { /* ... */ }72.

friend multi_ptr& operator+=(multi_ptr& lhs, difference_type r) { /* ... */ }73.

friend multi_ptr& operator-=(multi_ptr& lhs, difference_type r) { /* ... */ }74.

friend multi_ptr operator+(const multi_ptr& lhs, difference_type r) { /* ... */ }75.

friend multi_ptr operator-(const multi_ptr& lhs, difference_type r) { /* ... */ }

76.
77.

void prefetch(size_t NumElements) const;

78.
79.

friend bool operator==(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }80.

friend bool operator!=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }81.

friend bool operator<(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }82.

friend bool operator>(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }83.

friend bool operator<=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }84.

friend bool operator>=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }第 4 章 SYCL プログラミング・インターフェイス | 199

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
85.
86.

friend bool operator==(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }87.

friend bool operator!=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }88.

friend bool operator<(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }89.

friend bool operator>(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }90.

friend bool operator<=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }91.

friend bool operator>=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }

92.
93.

friend bool operator==(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }94.

friend bool operator!=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }95.

friend bool operator<(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }96.

friend bool operator>(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }97.

friend bool operator<=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }98.

friend bool operator>=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }

99.
100.

};

101.
102.

// 1.2.1 から継承されたレガシー・インターフェイス。

103.

// 非推奨。

104.

// void および const void の multi_ptr の特殊化

105.

// VoidType は void または const void のいずれかです106.

template <access::address_space Space>107.

class [[deprecated]] multi_ptr<VoidType, Space, access::decorated::legacy> {108.

public:109.

using element_type = VoidType;110.

using difference_type = std::ptrdiff_t;

111.
112.

// OpenCL C 関数の SYCL / OpenCL 相互運用性タイプに対応する

113.

// 実装定義のポインターおよび参照タイプ

114.

using pointer_t = multi_ptr<VoidType, Space, access::decorated::yes>::pointer;

115.

using const_pointer_t = multi_ptr<const VoidType, Space, access::decorated::yes>::pointer;

116.
117.

static constexpr access::address_space address_space = Space;

118.
119.

// コンストラクター120.

multi_ptr();

121.

multi_ptr(const multi_ptr&);

122.

multi_ptr(multi_ptr&&);123.

multi_ptr(pointer_t);

124.

multi_ptr(VoidType*);125.

multi_ptr(std::nullptr_t);

126.

~multi_ptr();

127.
128.

// 割り当て操作

129.

multi_ptr& operator=(const multi_ptr&);130.

multi_ptr& operator=(multi_ptr&&);131.

multi_ptr& operator=(pointer_t);

132.

multi_ptr& operator=(VoidType*);133.

multi_ptr& operator=(std::nullptr_t); 134

134.
135.

// Space == global_space の場合に利用可能

136.

template <typename ElementType, int Dimensions, access_mode Mode>200 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ137.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::device>);

138.
139.

// Space == local_space の場合に利用可能

140.

template <typename ElementType, int Dimensions, access_mode Mode>141.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::local>);

142.
143.

// Space == constant_space の場合に利用可能

144.

template <typename ElementType, int Dimensions, access_mode Mode>

145.

multi_ptr(accessor<ElementType, Dimensions, Mode, target::constant_buffer>);

146.
147.

// ベースとなる OpenCL の C ポインターを返します148.

pointer_t get() const;

149.
150.

// ベースとなるポインタータイプへの暗黙的変換

151.

operator VoidType*() const;

152.
153.

// multi_ptr<ElementType> への明示的な変換

154.

// VoidType が const の場合、ElementType も同様です155.

template <typename ElementType>156.

explicit operator multi_ptr<ElementType, Space, access::decorated::legacy>() const;

157.
158.

// multi_ptr<const void, Space> への暗黙の変換

159.

operator multi_ptr<const void, Space, access::decorated::legacy>() const;

160.
161.

friend bool operator==(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }162.

friend bool operator!=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }163.

friend bool operator<(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }164.

friend bool operator>(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }165.

friend bool operator<=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }166.

friend bool operator>=(const multi_ptr& lhs, const multi_ptr& rhs) { /* ... */ }

167.
168.

friend bool operator==(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }169.

friend bool operator!=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }170.

friend bool operator<(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }171.

friend bool operator>(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }172.

friend bool operator<=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }173.

friend bool operator>=(const multi_ptr& lhs, std::nullptr_t) { /* ... */ }

174.
175.

friend bool operator==(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }176.

friend bool operator!=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }177.

friend bool operator<(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }178.

friend bool operator>(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }179.

friend bool operator<=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }180.

friend bool operator>=(std::nullptr_t, const multi_ptr& rhs) { /* ... */ }

181.

};

182.
183.

} // namespace sycl

第 4 章 SYCL プログラミング・インターフェイス | 201

SYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ

4.7.7.2. 明示的なポインターエイリアス
SYCL は、access::address_space のそれぞれの特殊化に multi_ptr クラス・テンプレート (4.7.7.1 節を参照) へのエイリアスを提供します。
以下に、SYCL multi_ptr クラス・テンプレート・エイリアスの概要を示します。
1.

namespace sycl {2.
3.

template <typename ElementType, access::address_space Space, access::decorated IsDecorated>

4.

class multi_ptr;

5.
6.

// 異なるポインターアドレス空間のテンプレート特殊化エイリアス

7.
8.

template <typename ElementType, access::decorated IsDecorated = access::decorated::legacy>

9.

using global_ptr = multi_ptr<ElementType, access::address_space::global_space,

10.

IsDecorated>;

11.
12.

template <typename ElementType, access::decorated IsDecorated = access::decorated::legacy>

13.

using local_ptr = multi_ptr<ElementType, access::address_space::local_space,

14.

IsDecorated>;

15.
16.

// SYCL 2020 では非推奨

17.

template <typename ElementType>18.

using constant_ptr = multi_ptr<ElementType, access::address_space::constant_space,

19.

access::decorated::legacy>;

20.
21.

template <typename ElementType, access::decorated IsDecorated = access::decorated::legacy>

22.

using private_ptr = multi_ptr<ElementType, access::address_space::private_space,

23.

IsDecorated>;

24.
25.

// 異なるポインターアドレス空間のテンプレート特殊化エイリアス。

26.

// インターフェイスはアドレス空間情報を内部に保持して、

27.

// 修飾されていないポインターを公開します。

28.
29.

template <typename ElementType>30.

using raw_global_ptr = multi_ptr<ElementType, access::address_space::global_space,

31.

access::decorated::no>;

32.
33.

template <typename ElementType>34.

using raw_local_ptr = multi_ptr<ElementType, access::address_space::local_space,

35.

access::decorated::no>;

36.
37.

template <typename ElementType>38.

using raw_private_ptr = multi_ptr<ElementType, access::address_space::private_space,39.

access::decorated::no>;

40.
41.

// 異なるポインターアドレス空間のテンプレート特殊化エイリアス。

42.

// インターフェイスは修飾されたポインターを提供します。

43.
44.

template <typename ElementType>45.

using decorated_global_ptr = multi_ptr<ElementType, access::address_space::global_space,202 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.7 SYCL のデータアクセスとストレージ
46.

access::decorated::yes>;

47.
48.

template <typename ElementType>49.

using decorated_local_ptr = multi_ptr<ElementType, access::address_space::local_space,

50.

access::decorated::yes>;

51.
52.

template <typename ElementType>53.

using decorated_private_ptr = multi_ptr<ElementType, access::address_space::private_space,

54.
55.

access::decorated::yes>;} // namespace sycl

修飾を指定せずに、global_ptr、local_ptr、constant_ptr または private_ptr を使用するのは非推奨であることに留意してください。
デフォルトの引数は 1.2.1 との互換性を提供します。

4.7.8. イメージサンプラー
SYCL image_sampler 構造体には、sampled_image をサンプルする設定が含まれています。この構造体のメンバーは次のように定義されます。
1.

namespace sycl {2.
3.

enum class addressing_mode : /* 未定義 */ {4.

mirrored_repeat,5.

repeat,6.

clamp_to_edge,

7.

clamp,

8.
9.

none
};

10.
11.

enum class filtering_mode : /* 未定義 */ {12.

nearest,13.
14.

linear};15.
16.

enum class coordinate_normalization_mode : unsigned int {17.

normalized,

18.
19.

unnormalized
};

20.
21.

struct image_sampler {22.

addressing_mode addressing;23.

coordinate_mode coordinate;24.

filtering_mode filtering;

25.

};

26.
27.

} // namespace sycl

第 4 章 SYCL プログラミング・インターフェイス | 203

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
表 96. アドレス指定モード記述子
addressing_mode

説明mirrored_repeat

レンジ外の座標はすべての整数ジャンクションで反転されます。
このアドレス指定モードは正規化された座標のみに使用できます。座標が正規化されていない場合、このアドレス指定モードは
未定義のイメージ座標を生成する可能性があります。

repeat

レンジ外のイメージ座標は有効な範囲にラップされます。このア
ドレス指定モードは正規化された座標のみに使用できます。座標が正規化されていない場合、このアドレス指定モードは未定義のイメージ座標を生成する可能性があります。

clamp_to_edge

レンジ外のイメージ座標はエクステントにクランプされます。

clamp

レンジ外のイメージ座標は境界の色を返します。

none

このアドレス指定モードでは、プログラマーがイメージの要素をサンプリングする際に使用するイメージ座標がイメージ内の場所を参照することが保証されます。それ以外の結果は未定義です。

表 97. アドレス指定モード記述子
filtering_mode

説明nearest

最も近いピクセルの色を選択します。

linear

隣接するピクセルの線形サンプリングを実行します。

表 98. 座標正規化モードの説明
coordinate_normalization_mode

説明normalized

イメージの座標を正規化します。

unnormalized

イメージの座標を正規化しません。

4.8. 統合共有メモリー (USM)
ここでは、SYCL のポインターベースのメモリー管理インターフェイスのプロパティーとルーチンについて説明します。これらのルーチ
ンは、SYCL のバッファーベースのインターネットを置き換えるのではなく拡張します。
統合共有メモリー (USM) は、バッファー・プログラミング・モデルによるポインターベースの代替手段を提供します。USM は以下を可能にします。

• 割り当てアクセスをバッファーの代わりにポインターとすることにより、既存のコードベースへの統合が容易となり、割り当てられたメモリーへのポインター操作が完全にサポートされます。

204 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)• パフォーマンスとプログラマーの利便性を適切に選択するため、割り当ての所有権とアクセスを細かく制御できます。
• SYCL デバイスとホスト間で割り当てを自動的に移行する単純なプログラミング・モデルを実現します。
3.2 節の例との違いを示すため、以下のソースではホストとデバイス間で共有メモリーを使用する方法を示します。
1.

#include <iostream>2.

#include <sycl/sycl.hpp>

3.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

4.
5.

int main() {6.

// デフォルトキューを作成して、ワークをデフォルトデバイスへ送信します

7.

queue myQueue;

8.
9.

// デバイスにバインドされた共有メモリーとキューに関連するコンテキストを割り当て

10.

// malloc_shared を malloc_host に置き換えると、デバイスで使用可能なメモリーを

11.

// ホストに割り当てたプログラムを作成できます。

12.

int* data = sycl::malloc_shared<int>(1024, myQueue);

13.
14.

myQueue.parallel_for(1024, [=](id<1> idx) {15.

// 0 から始まるランク番号でそれぞれのバッファー要素を初期化

16.

data[idx] = idx;

17.

}); // カーネル関数の終端

18.
19.

// アクセサーを使用しないため、カーネルの実行を明示的に待機します20.

myQueue.wait();

21.
22.

// 結果をプリント

23.

for (int i = 0; i < 1024; i++)24.

std::cout <<"data["<< i << "] = " << data[i] << std::endl;

25.
26.
27.

return 0;}

次のソースコードの例と比較すると、性能の低いデバイスメモリーを使用しているため、デバイスとホスト間で明示的なコピーが必要です。
1.

#include <iostream>2.

#include <sycl/sycl.hpp>

3.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

4.
5.

int main() {6.

// デフォルトキューを作成して、ワークをデフォルトデバイスへ送信します

7.

queue myQueue;

8.
9.

// デバイスにバインドされた共有メモリーとキューに関連するコンテキストを割り当て

10.

int* data = sycl::malloc_device<int>(1024, myQueue);

11.
12.
13.
14.
15.

myQueue.parallel_for(1024, [=](id<1> idx) {// 0 から始まるランク番号でそれぞれのバッファー要素を初期化
data[idx] = idx;}); // カーネル関数の終端

16.

第 4 章 SYCL プログラミング・インターフェイス | 205

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
17.

// アクセサーを使用しないため、カーネルの実行を明示的に待機します18.

myQueue.wait();

19.
20.

// デバイスのコンテンツを受け取る配列を作成します21.

int hostData[1024];

22.

// デバイスからコンテンツを受信します23.

myQueue.memcpy(hostData, data, 1024*sizeof(int));

24.

// コピーが完了するのを待機します25.

myQueue.wait();

26.
27.

// 結果をプリント

28.

for (int i = 0; i < 1024; i++)29.

std::cout <<"hostData["<< i << "] = " << hostData[i] << std::endl;

30.
31.
32.

return 0;}

4.8.1. 統合アドレス指定
統合アドレス指定は、すべてのデバイスが統合アドレス空間を使用することを保証します。統合アドレス空間のポインター値は、常にメモリー上の同じ場所を指します。統合アドレス空間には、ホストと 1 つ以上のデバイスが関連します。これは、すべてのデバイスが統合
アドレス空間のアドレスにアクセスできる必要はなく、ポインター値が一貫しているだけであることに注意してください。

4.8.2. 統合共有メモリーの種類
USM は、利用可能であれば、ホストとデバイスの両方でアクセス可能な割り当てを行う機能を提供します。USM は、統合アドレス指定
によって共有アドレス空間を定義します。この空間のポインター値は常に同じメモリー位置を参照します。USM は表 99 で説明される
3 種類のメモリー割り当てを定義します。
表 99. USM 割り当てのタイプ
USM 割り当てタイプ

説明

host

デバイスからアクセス可能なホストメモリー割り当て

deviceホストからアクセスできないデバイスメモリー割り当て

sharedデバイスとホストの両方からアクセス可能な共有メモリー割り当て

次の列挙型は、SYCL プログラム内の各種タイプの割り当てを参照するため使用されます。
1.

namespace sycl {2.

namespace usm {3.

enum class alloc : /* 未定義 */ {

4.

host,

5.

device,6.

shared,7.

unknown

8.

}；

9.
10.

｝
}

206 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
USM はオプション機能であり、すべてのデバイスでサポートされるとは限りません。また、USM をサポートするデバイスが、すべてのUSM 割り当てタイプを提供するとは限りません。USM を利用するアプリケーションは、device::has() 関数を使用してデバイスの USM
サポートレベルを決定できます。詳細は 4.6.4.3 節の表 26 を参照してください。
USM 割り当ての特徴を表 100 に示します。
表 100. 各種 USM 割り当ての特徴
割り当てタイプ

初期の場所

アクセス元

devicedevice

host

いいえ

host

いいえ

deviceはいdeviceN/A

ほかの device

オプション (P2P)

ほかの device

いいえ

host

はい

host

N/A

すべての device

はいdevice

いいえ

host

はい

host

はい

deviceはいdeviceはいほかの device

オプション

ほかの device

オプション

host

shared

host

未定義

移行先

それぞれの USM 割り当てには、関連付けられた SYCL コンテキストがあり、そのメモリーへのアクセスは同じコンテキストを使用する必要があります。具体的には、USM 割り当てへのポインターを逆参照する SYCL カーネル関数は、そのメモリーを割り当てたコンテキ
ストで構築されたキューに送信される必要があります。USM ポインターを受け取る明示的なメモリー操作コマンドも同様の制約を受けます。詳細は、4.9.4.3 節を参照してください。これらの制限に違反すると動作は未定義となります。
ホストタスクの USM ポインターの逆参照には、このような制約はありません。USM ポインターがホスト上でアクセス可能である限り、ホストタスクがどのキューにエンキューされても逆参照できます。
USM 割り当てのタイプごとに、メモリーがアクセス可能な場所に関する規則が異なります。それらの規則に違反してホストやデバイス
で USM ポインターを逆参照すると、未定義の動作となります。USM ポインターをデバイスからアクセスできないメモリー関数に渡すと、未定義の動作となる可能性があります。規則に関する詳細は、4.9.4.3 節を参照してください。
デバイス割り当ては、デバイスメモリーを明示的に管理する目的で使用されます。プログラマーは、デバイスメモリーを直接割り当てて、ホストメモリーとデバイス割り当てメモリー間でデータを明示的にコピーします。デバイス割り当てメモリーは、std::malloc や C++
new などのシステムで提供される割り当てルーチンではなく、SYCL USM デバイス割り当てルーチンを利用して取得されます。ホストからデバイスに割り当てられたメモリーにアクセスすることはできませんが、統合アドレス指定であるためポインター値には一貫性があります。デバイス割り当てメモリーのサイズは、デバイスに搭載されるメモリー容量によって制限されます。特定のデバイスにおけるデバイス割り当てのサポート状況は、aspect::usm_device_allocations を介して照会できます。
デバイス割り当てでは、ホストとデバイス間で明示的にデータをコピーする必要があります。データをコピーおよび初期化するメンバー
関数は、表 28 および表 134 に示しますが、デバイスが aspect::usm_device_allocations をサポートする場合、これらの関数をデバ
イス割り当てに使用できます。

第 4 章 SYCL プログラミング・インターフェイス | 207

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
ホスト割り当てでは、デバイスはカーネル内のホストメモリーを直接読み書きできます。これは、少量のデータを移動するオーバーヘッドがリモートアクセスのコストに見合わない場合や、データセットのサイズがデバイスのメモリーサイズを超える場合などに有用です。
ホスト割り当ては、システムの割り当てルーチンの代わりに SYCL ルーチンを使用して取得する必要があります。デバイスはリモートホ
スト割り当てのメモリーを読み書きできますが、割り当てはデバイスに移行されず、ホストメモリーに残されたままです。ユーザーは、ホストの実行とカーネル間でホスト割り当てのアクセスを適切に同期することに注意しなければなりません。ホスト割り当ての合計サイズは、システムのホスト上に張り付け可能なメモリー量によって制限されます。特定のデバイスにおけるホスト割り当てのサポートは、
aspect::usm_host_allocations を介して照会できます。特定のデバイスにおけるホスト割り当てのアトミック更新のサポート状況は、
aspect::usm_atomic_host_allocations を介して照会できます。
共有割り当ては、ホストとデバイス間で暗黙的にデータを共有します。データはプログラマーが明示的にランタイムに指示しなくても、使用される場所に移動されることがあります。共有割り当てが要求される場所で利用可能であるかどうかはランタイムとバックエンド
次第です。共有割り当てメモリーは、システムの割り当てルーチンの代わりに、SYCL 割り当てルーチンを使用して取得する必要があります。特定のデバイス上の共有割り当ての最大サイズ、およびコンテキスト内のすべての共有割り当てサイズの合計は、実装定義です。
特定のデバイスにおける共有割り当てのサポートは、aspect::usm_shared_allocations を介して照会できます。
すべてのデバイスが、ホストとの共有割り当ての同時アクセスをサポートするわけではありません。デバイスがサポートしない場合、ホストの実行とデバイスコードが交互に割り当てにアクセスする必要があるため、カーネル実行中にホストが共有割り当てにアクセス
してはなりません。同時アクセスをサポートしないデバイスでは、カーネルとホストからの共有割り当てへの同時アクセスは未定義の動作となります。デバイスが同時アクセスをサポートする場合、ホストとデバイスの両方が割り当て内の同一データをアトミックに更新する可能性があります。割り当て全体、または部分的な割り当ては、この機能をサポートする同じコンテキスト内の異なるデバイス
間で自由に移行できるようになりました。さらに、同時アクセスをサポートする多くのデバイスでは、デバイスメモリーよりも大きな共有割り当てのワーキングセットをサポートする場合があります。ユーザーは、aspect::usm_atomic_shared_allocations を介して、デバイスが共有割り当てのアトミック更新を伴う同時アクセスをサポートするか照会できます。詳細について、4.6.4.3 節の表 26 を参照してください。
共有割り当てのパフォーマンスのヒントは、ユーザーがデバイスで prefetch 操作をキューに投入することで指示できます。これらの操作は、指定された共有割り当てが今後デバイスでアクセスされる可能性があり、割り当てをデバイスに移行できることを SYCL ランタイ
ムに通知します。prefetch に関する詳細は、表 28 と表 134 をご覧ください。デバイスが共有割り当てへの同時アクセスをサポートする場合、prefetch 操作がカーネルの実行とオーバーラップする可能性があります。
さらに、ユーザーは mem_advise メンバー関数を使用して、共有割り当てに対しアドバイス付きのアノテーションを指定することができます。有効なアドバイスは、デバイスと関連するバックエンドで定義されます。詳しくは、表 28 と表 134 をご覧ください。
最も能力が高いシステムでは、ユーザーが共有割り当てを作成するため SYCL USM 割り当て機能を使用する必要がありません。シス
テム・アロケーター (malloc/new) を使用することができます。同様に、sycl::free の代わりに std::free と delete を使用します。ホストとデバイス割り当てはこの影響を受けませんが、動作を保証するため USM 機能を使用して割り当てを行う必要があります。ユーザーは、
aspect::usm_system_allocations を使用してデバイスを照会することで、システム割り当てがデバイスをサポートするかどうかを確認できます。

4.8.3. USM 割り当て
USM はいくつかの割り当て機能をサポートします。これらの関数は、今後の拡張性のため提供される property_list パラメーターを受け入れます。コア SYCL 仕様では USM 割り当てのプロパティーはまだ定義されていません。
割り当て関数には、明示的なアライメント・パラメーターを受け取るものもあります。std::aligned_alloc と同様に、それらの関数はアライメントが実装でサポートされていない場合、nullptr を返します。割り当て関数には、割り当てタイプ T にテンプレート化されているものもあります。次の表に、それぞれのカテゴリーで保証されるアライメントを示します。

208 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
表 101. USM 割り当て関数のアライメントの保証
カテゴリー

アライメントの保証

アライメント・パラメーターなしで、割り当てタイプでテン ポインターは、要求された割り当てサイズ以下のサイズでアライメント
プレート化されていないされたオブジェクトにアライメントされます。

アライメント・パラメーターなしで、割り当てタイプ T でテ ポインターは、タイプ T のオブジェクトにアライメントされます。
ンプレート化されている
アライメント・パラメーター alignment が指定され、割り ポインターは、要求された割り当てサイズ以下でアライメントされたオ
当てタイプでテンプレート化されていない

ブジェクト、または指定された alignment のいずれか大きいほうにアライメントされます。

アライメント・パラメーター alignment が指定され、割り ポインターは、タイプ T のオブジェクト、または指定された alignment
当てタイプ T でテンプレート化されているのいずれか大きいほうにアライメントされます。

4.8.3.1. C++ アロケーター・インターフェイスSYCL では、C++ の名前付き要件 Allocator を満たす usm_allocator アロケーター・クラスを定義しています。AllocKind テンプレー
ト・パラメーターは、usm::alloc::host または usm::alloc::shared のいずれかで、アロケーターはホスト USM 割り当て、または共有
USM 割り当てを行います。
ホスト上でアクセスできるメモリーを割り当てるには Allocator が必要であり、usm::alloc::device の特殊化はありません。
usm_allocator クラスには、割り当ての最小メモリー・アライメントを指定する Alignment テンプレート・パラメーターがあります。このアライメントは、アロケーターが異なるタイプに再バインドされた場合にも使用されます。このアロケーターで割り当てられたメモ
リーは、value_type のオブジェクト、または Alignment で指定されたアライメントのいずれか大きいほうにアライメントされます。
usm_allocator クラスの概要を以下に示します。表 102 にコンストラクターを示します。
1.

template <typename T, usm::alloc AllocKind, size_t Alignment = 0>2.

class usm_allocator {3.

public:4.

using value_type = T;5.

using propagate_on_container_copy_assignment = std::true_type;6.

using propagate_on_container_move_assignment = std::true_type;7.

using propagate_on_container_swap = std::true_type;

8.
9.
10.

public:template <typename U> struct rebind {

11.
12.

typedef usm_allocator<U, AllocKind, Alignment> other;
};

13.
14.

usm_allocator() = delete;15.

usm_allocator(const context& syclContext,

16.

const device& syclDevice,17.

const property_list& propList = {});

18.

usm_allocator(const queue& syclQueue,

第 4 章 SYCL プログラミング・インターフェイス | 209

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
19.

const property_list& propList = {});

20.

usm_allocator(const usm_allocator& other);21.

usm_allocator(usm_allocator&&) noexcept;

22.

usm_allocator& operator=(const usm_allocator&);23.

usm_allocator& operator=(usm_allocator&&);

24.
25.

template <class U>

26.

usm_allocator(usm_allocator<U, AllocKind, Alignment> const&) noexcept;

27.
28.

/// メモリーを割り当て

29.

T* allocate(size_t count);

30.
31.

/// メモリーを解放

32.

void deallocate(T* Ptr, size_t count);

33.
34.

/// 同等性比較

35.

///

36.

/// アロケーターは、同じ種類の USM、アライメント、コンテキスト、およびデバイスである場合にのみ、

37.

/// 同等であると見なされます38.

template <class U, usm::alloc AllocKindU, size_t AlignmentU>

39.

friend bool operator==(const usm_allocator<T, AllocKind, Alignment>&,

40.

const usm_allocator<U, AllocKindU, AlignmentU>&);

41.
42.

/// 不等比較

43.

/// アロケーターは、同じ種類の USM、アライメント、コンテキスト、およびデバイスが44.

/// 同じでない場合にのみ、等しくないと見なします。

45.

template <class U, usm::alloc AllocKindU, size_t AlignmentU>

46.

friend bool operator!=(const usm_allocator<T, AllocKind, Alignment>&,

47.

const usm_allocator<U, AllocKindU, AlignmentU>&);

48.

};

表 102. usm_allocator クラスのコンストラクター
コンストラクター

説明

usm_allocator(const context& syclContext,

指定されたコンテキストとデバイスに対し、USM メモリーを割り

const device& syclDevice,
const property_list& propList = {})当てる usm_allocator インスタンスを作成します。
AllocKind が usm::alloc::host で あ る 場 合 、 syclContex に
aspect::usm_host_allocations を持つデバイスがなければ、コンストラクターは errc::feature_not_supported エラーモードの同期例外をスローします。この割り当てタイプでは、syclDeviceは無視されます。
AllocKind が usm::alloc::shared である場合、 syclDevice に
aspect::usm_shared_allocations を持つデバイスがなければ、
コンストラクターは errc::feature_not_supported エラーモードの同期例外をスローします。
syclDevice は syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスである必要があります。そうでない場合、このコンストラクターは errc::invalid エラーコードで同期例外をスローする必要があります。

210 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)

コンストラクター

説明

usm_allocator(const queue& syclQueue,

syclQueue が device と context を提供するコンストラクター

const property_list& propList = {})の省略形。

4.8.3.2. デバイス割り当て関数
表 103 に示す関数でデバイス USM を割り当てます。割り当てに成功すると、これらの関数は新たに割り当てられたメモリーへのポイン
ターを返します。この USM 割り当ては、メモリーリークを避けるため、最終的に sycl::free で解放する必要があります。要求されたメモ
リーを割り当てる十分なリソースがない場合、これらの関数は nullptr を返します。
表 103. USM デバイスメモリー割り当て関数
関数

説明

void* sycl::malloc_device(size_t numBytes,

成功すると syclDevice に新たに割り当てられたメモリーへのポconst device& syclDevice,

インターを返します。割り当てサイズはバイト単位で指定します。

const context& syclContext,

syclDevice に aspect::usm_device_allocations がない場合、const property_list& propList ={})

errc::feature_not_supported エラーコードで同期例外をスローします。syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。
そうでない場合、errc::invalid エラーコードで同期例外をスローします。

template <typename T>

成功すると syclDevice に新たに割り当てられたメモリーへのポT* sycl::malloc_device(size_t count,

インターを返します。割り当てサイズはタイプ T の要素数で指定

const device& syclDevice,

します。syclDevice に aspect::usm_device_allocations がない

const context& syclContext,

場合、errc::feature_not_supported エラーコードで同期例外をconst property_list& propList = {})スローします。syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をス
ローします。

void* sycl::malloc_device(size_t numBytes,

syclQueue が device と context を提供する省略形。

const queue& syclQueue,
const property_list& propList ={})
template <typename T>

syclQueue が device と context を提供する省略形。

T* sycl::malloc_device(size_t count,
const queue& syclQueue,
const property_list& propList = {})第 4 章 SYCL プログラミング・インターフェイス | 211

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)関数

説明

void* sycl::aligned_alloc_device(size_t alignment,

成功すると、syclDevice に新たに割り当てられたメモリーへのポ

size_t numBytes,

インターを返します。割り当てサイズはバイト単位で指定し、割り

const device& syclDevice,

当 て は alignment で ア ラ イ メ ン ト さ れ ま す 。 syclDevice に

const context& syclContext,

aspect::usm_device_allocations が な い 場 合 、 errc::feature_

const property_list& propList ={})

not_supported エ ラ ー コ ー ド で 同 期 例 外 を ス ロ ー し ま す 。
syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をスローします。

template <typename T>

成功すると、syclDevice に新たに割り当てられたメモリーへのT* sycl::aligned_alloc_device(size_t alignment,

ポインターを返します。割り当てサイズはタイプ T の要素数で指size_t count,

定 し 、 割 り 当 て は alignment で ア ラ イ メ ン ト さ れ ま す 。

const device& syclDevice,

syclDevice に aspect::usm_device_allocations が な い 場

const context& syclContext,

合、errc::feature_not_supported エラーコードで同期例外をconst property_list& propList ={})

スローします。syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例
外をスローします。

void*

syclQueue が device と context を提供する省略形。

sycl::aligned_alloc_device(size_t alignment,
size_t numBytes,
const queue& syclQueue,
const property_list& propList ={})
template <typename T>

syclQueue が device と context を提供する省略形。

T* sycl::aligned_alloc_device(size_t alignment,
size_t count,
const queue& syclQueue,
const property_list& propList ={})

4.8.3.3. ホスト割り当て関数
表 104 に示す関数でホスト USM を割り当てます。割り当てに成功すると、これらの関数は新たに割り当てられたメモリーへのポイン
ターを返します。この USM 割り当ては、メモリーリークを避けるため、最終的に sycl::free で解放する必要があります。要求されたメモ
リーを割り当てる十分なリソースがない場合、これらの関数は nullptr を返します。
表 104. USM ホストメモリー割り当て関数
関数

説明

void* sycl::malloc_host(size_t numBytes,

成功すると新たに割り当てられたメモリーへのポインターを返し

const context& syclContext,

ま す 。 割 り 当 て は バ イ ト 単 位 で 指 定 し ま す 。 syclContext にconst property_list& propList = {})aspect::usm_host_allocations が な い 場 合 、 errc::feature_
not_supported エラーコードで同期例外をスローします。

212 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)関数

説明

template <typename T>

成功すると新たに割り当てられたメモリーへのポインターを返しT* sycl::malloc_host(size_t count,

ま す 。 割 り 当 て サ イ ズ は 、 タイ プ T の 要 素 数 で 指 定 し ま す 。

const context& syclContext,

syclContext に aspect::usm_host_allocations がない場合 、

const property_list& propList = {})errc::feature_not_supported エラーコードで同期例外をスローします。

void* sycl::malloc_host(size_t numBytes,

syclQueue が context を提供する省略形。

const queue& syclQueue,
const property_list& propList = {})template <typename T>

syclQueue が context を提供する省略形。

T* sycl::malloc_host(size_t count,
const queue& syclQueue,
const property_list& propList = {})void* sycl::aligned_alloc_host(size_t alignment,

成功すると新たに割り当てられたメモリーへのポインターを返し

size_t numBytes,

ます。割り当てはバイト単位で指定し、割り当ては alignment でconst context& syclContext,

ア ラ イ メ ン ト さ れ ま す 。 syclContext にconst property_list& propList ={})

host_allocations が な い 場 合 、 errc::feature_not_supported

aspect::usm_

エラーコードで同期例外をスローします。
template <typename T>

成功すると 新たに割り当てられたメモリーへのポインターを返しT* sycl::aligned_alloc_host(size_t alignment,

ます。割り当てはタイプ T の要素で指定し、割り当ては alignment

size_t count,で ア ラ イ メ ン ト さ れ ま す 。 syclContext に aspect::usm_

const context& syclContext,

host_allocations が な い 場 合 、 errc::feature_not_supported

const property_list& propList ={})

エラーコードで同期例外をスローします。

void* sycl::aligned_alloc_host(size_t alignment,

syclQueue が context を提供する省略形。

size_t numBytes,
const queue& syclQueue,
const property_list& propList ={})
template <typename T>

syclQueue が context を提供する省略形。

void* sycl::aligned_alloc_host(size_t alignment,
size_t count,
const queue& syclQueue,
const property_list& propList ={})

4.8.3.4. 共有割り当て関数
表 105 に示す関数で共有 USM を割り当てます。割り当てに成功すると、これらの関数は新たに割り当てられたメモリーへのポイン
ターを返します。この USM 割り当ては、メモリーリークを避けるため、最終的に sycl::free で解放する必要があります。要求されたメモ
リーを割り当てる十分なリソースがない場合、これらの関数は nullptr を返します。

第 4 章 SYCL プログラミング・インターフェイス | 213

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)
表 105. USM 共有メモリー割り当て関数
関数

説明

void* sycl::malloc_shared(size_t numBytes,

成功すると syclDevice に新たに割り当てられたメモリーへのポconst device& syclDevice,

インターを返します。割り当てサイズはバイト単位で指定します。

const context& syclContext,

syclDevice に aspect::usm_shared_allocations がない場合、const property_list& propList ={})

errc::feature_not_supported エラーコードで同期例外をスローします。syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。
そうでない場合、errc::invalid エラーコードで同期例外をスローします。

template <typename T>

成功すると syclDevice に新たに割り当てられたメモリーへのポT* sycl::malloc_shared(size_t count,

インターを返します。割り当てサイズはタイプ T の要素数で指定

const device& syclDevice,

します。syclDevice に aspect::usm_shared_allocations がない

const context& syclContext,

場合、errc::feature_not_supported エラーコードで同期例外をconst property_list& propList = {})スローします。syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をス
ローします。

void* sycl::malloc_shared(size_t numBytes,

syclQueue が device と context を提供する省略形。

const queue& syclQueue,
const property_list& propList ={})
template <typename T>

syclQueue が device と context を提供する省略形。

T* sycl::malloc_shared(size_t count,
const queue& syclQueue,
const property_list& propList = {})void* sycl::aligned_alloc_shared(size_t alignment,

成功すると syclDevice に新たに割り当てられたメモリーへのポ

size_t numBytes,

インターを返します。割り当てサイズはバイト単位で指定し、割り

const device& syclDevice,

当 て は alignment で ア ラ イ メ ン ト さ れ ま す 。 syclDevice に

const context& syclContext,

aspect::usm_shared_allocations が な い場 合 、 errc::feature_

const property_list& propList ={})

not_supported エ ラ ー コ ー ド で 同 期 例 外 を ス ロ ー し ま す 。
syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をスローします。

template <typename T>

成功すると syclDevice に新たに割り当てられたメモリーへのポT* sycl::aligned_alloc_shared(size_t alignment,

インターを返します。割り当てはタイプ T の要素数で指定し、割り

size_t count,

当 て は alignment で ア ラ イ メ ン ト さ れ ま す 。 syclDevice に

const device& syclDevice,aspect::usm_shared_allocations が な い場 合 、 errc::feature_

const context& syclContext,

not_supported エ ラ ー コ ー ド で 同 期 例 外 を ス ロ ー し ま す 。

const property_list& propList ={})

syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をスローします。

214 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)関数

説明

void* sycl::aligned_alloc_shared(size_t alignment,

syclQueue が device と context を提供する省略形。

size_t numBytes,
const queue& syclQueue,
const property_list&propList ={})
template <typename T>

syclQueue が device と context を提供する省略形。

T* sycl::aligned_alloc_shared(size_t alignment,
size_t count,
const queue& syclQueue,
const property_list& propList ={})

4.8.3.5. パラメーター化された割り当て関数
表 106 に示す関数は、割り当てる USM の種類を指定する kind パラメーターを受け取ります。kind が usm::alloc::device である場合、割り当てデバイスには aspect::usm_device_allocations が必要です。kind が usm::alloc::host の場合、割り当てコン
テキスト内の少なくとも 1 つのデバイスには aspect::usm_host_allocations が必要です。また、kind が usm::alloc::device である場合、割り当てデバイスには aspect::usm_device_allocations が必要です。これらの要件を満たさない場合、割り当て関数
は errc::feature_not_supported エラーコードで同期例外をスローします。
割り当てに成功すると、これらの関数は新たに割り当てられたメモリーへのポインターを返します。この USM 割り当ては、メモリーリー
クを避けるため、最終的に sycl::free で解放する必要があります。要求されたメモリーを割り当てる十分なリソースがない場合、これらの関数は nullptr を返します。
表 106. USM パラメーター化された割り当て関数
関数

説明

void* sycl::malloc(size_t numBytes,

成功すると新たに割り当てられたメモリーへの kind タイプのポイ

const device& syclDevice,

ンターを返します。割り当てサイズはバイト単位で指定します。

const context& syclContext, usm::alloc kind,

kind が usm::alloc::host である場合、syclDevice パラメーター

const property_list& propList = {})は 無 視 さ れ ま す 。 kind が usm::alloc::host で な い 場 合 、
syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をスローします。

template <typename T>

成功すると新たに割り当てられたメモリーへの kind タイプのポイ

T* sycl::malloc(size_t count,

ンターを返します。割り当てサイズはタイプ T の要素数で指定しconst device& syclDevice,ます。kind が usm::alloc::host である場合、syclDevice パラメー

const context& syclContext, usm::alloc kind,

ターは 無視さ れます。 kind が usm::alloc::host でない場 合、

const property_list& propList = {})syclDevice は、syclContext に含まれるか、そのコンテキストに含まれるデバイスの下位デバイスでなければなりません。そうでない場合、errc::invalid エラーコードで同期例外をスローします。

void* sycl::malloc(size_t numBytes,

syclQueue は context と必要な device を提供する省略形。

const queue& syclQueue, usm::alloc kind,const property_list& propList = {})第 4 章 SYCL プログラミング・インターフェイス | 215

SYCL 2020 リビジョン 6 - 4.8 統合共有メモリー (USM)関数

説明

template <typename T>

syclQueue は context と必要な device を提供する省略形。

T* sycl::malloc(size_t count,
const queue& syclQueue, usm::alloc kind,const property_list& propList = {})void* sycl::aligned_alloc(size_t alignment,

成功すると新たに割り当てられたメモリーへの kind タイプのポイ

size_t numBytes,

ンターを返します。割り当てサイズはバイト単位で指定し、割り当

const device& syclDevice,ては

const context& syclContext, usm::alloc kind,

usm::alloc::host である場合、syclDevice パラメーターは無視さconst property_list& propList ={})

れます。kind が usm::alloc::host でない場合、syclDevice は、alignment で ア ラ イ メ ン ト さ れ ま す 。 kind がsyclContext に含まれるか、そのコンテキストに含まれるデバイ
スの下位デバイスでなければなりません。そうでない場合、
errc::invalid エラーコードで同期例外をスローします。
template <typename T>

成功すると新たに割り当てられたメモリーへの kind タイプのポイ

T* sycl::aligned_alloc(size_t alignment,

ンターを返します。割り当てサイズはタイプ T の要素数で指定し、size_t count,

割 り 当 て は alignment で ア ラ イ メ ン ト さ れ ま す 。 kind がconst device& syclDevice,

usm::alloc::host である場合、syclDevice パラメーターは無視さconst context& syclContext, usm::alloc kind,

れます。kind が usm::alloc::host でない場合、syclDevice は、

const property_list& propList = {})syclContext に含まれるか、そのコンテキストに含まれるデバイ
スの下位デバイスでなければなりません。そうでない場合、
errc::invalid エラーコードで同期例外をスローします。

void* sycl::aligned_alloc(size_t alignment,

syclQueue は context と必要な device を提供する省略形。

size_t numBytes,
const queue& syclQueue, usm::alloc kind,const property_list& propList ={})
template <typename T>

syclQueue は context と必要な device を提供する省略形。

T* sycl::aligned_alloc(size_t alignment,
size_t count,
const queue& syclQueue, usm::alloc kind,const property_list& propList = {})4.8.3.6. メモリー割り当て解除関数
表 107. USM 解放関数
関数

説明

void sycl::free(void* ptr, const context& syclContext)

割り当てを解放します。ptr が指すメモリーは USM 割り当てルー
チンを使用して割り当てられている必要があります。syclContext
はメモリー割り当てに使用されるのと同じ context でなければなりません。メモリーを操作するコマンドの完了を待たずにメモリーを解放できます。メモリーを使用するコマンドが処理中であった
り、キューに投入されている場合の動作は未定義です。

216 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

void sycl::free(void* ptr, const queue& syclQueue)

syclQueue が context を提供する代替形式です。

4.8.4. 統合共有メモリーポインター照会
USM ポインターは従来の C++ ポインターのように見えるため、ユーザーはタイプを調査してもポインターがどのような USM 割り当てであるかを推測できません。ただし、ユーザーが USM 割り当てタイプと、該当する場合は、割り当てられている device を照会できる 2つの関数が定義されています。これらの照会はホストでのみサポートされます。
表 108. USM ポインターの照会関数
関数

説明

usm::alloc get_pointer_type(const void* ptr,

ptr が有効な USM 割り当て内にある場合、ptr の USM 割り当て

const context& ctxt)

タイプを返します。ptr が syclContext の有効な USM 割り当て内にない場合、usm::alloc::unknown を返します。

sycl::device get_pointer_device(const void* ptr,
const context& ctxt)

USM 割 り 当 て に 関 連 付 け ら れ た device を 返 し ま す 。 ptr がsyclContext のデバイス USM 割り当てや共有 USM 割り当て内のメモリーを指している場合、割り当て時に渡されたのと同じデバイスを返します。ptr が syclContext のホスト USM 割り当て内を指している場合、syclContext 内の最初のデバイスを返します。
ptr が syclContext の有効な USM 割り当て内を指していない場
合、errc::invalid エラーコードで同期例外をスローします。

4.9. カーネルを介して並列処理を表現
4.9.1. レンジとインデックス空間識別子
SYCL カーネル実行モデルのデータ並列処理では、反復空間座標のレンジで並列実行をインスタンス化する必要があります。これを実現するため、SYCL はタイプを公開して実行レンジを定義し、反復空間内の特定の実行インスタンスの位置を識別します。
range、nd_range、id、item、h_item、nd_item、および group タイプが定義されています。
整数から多次元 id または range を構築する場合、要素は多次元空間の線形化で右端の要素が最も高速に変化するように記述されます (3.11.1 節を参照)。
表 109. インデックス空間内の位置を識別する際に使用されるタイプのサマリー、および位置が変化する可能性があるレンジ
タイプ

説明

id

レンジ内をポイント

range

id が変化する可能性がある境界

item

id (特定の位置) と制限される range のペアリングします

第 4 章 SYCL プログラミング・インターフェイス | 217

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

タイプ

説明

nd_range

work-item id が変化するグローバルおよびローカル (workgroup サイズ) の両方の range をカプセル化します

nd_item

2 つの item をカプセル化します。1 つはグローバル id と range
で、もう 1 つはローカル id と range です

h_item

階層的な並列処理 (parallel_for_work_item) 内のインデックス
位置を照会します。物理的なグローバルおよびローカル id とrange、階層的な並列処理で定義される論理的なローカル id とrange をカプセル化しますgroup

階 層 的 な 並 列 処 理 (parallel_for_work_group) 内 の workgroup 照会、および各 work-item で実行されるコードを識別する
parallel_for_work_item 構造を公開します。work-group id とrange をカプセル化します

4.9.1.1. range クラス
range<int Dimensions> は、並列ディスパッチ内の単一 work-group の反復ドメイン、またはディスパッチ全体の次元を定義する 1D、2D または 3D ベクトルを示します。これは整数から構築できます。
SYCL range クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL range クラスの概要を以下に示します。SYCL range クラスのコンストラクター、メンバー関数、および非メンバー関数について
は、表 110、表 111 および表 112 をご覧ください。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表10 を参照してください。
1.

namespace sycl {2.

template <int Dimensions = 1>

3.

class range {4.

public:5.

/* 次のコンストラクターは、range クラスの特殊化でのみ使用できます (Dimensions==1) */6.

range(size_t dim0);7.

/* 次のコンストラクターは、range クラスの特殊化でのみ使用できます (Dimensions==2) */8.

range(size_t dim0, size_t dim1);

9.

/* 次のコンストラクターは、range クラスの特殊化でのみ使用できます (Dimensions==3) */10.

range(size_t dim0, size_t dim1, size_t dim2);

11.
12.

/* -- 共通インターフェイスのメンバー -- */

13.
14.

size_t get(int dimension) const;

15.

size_t& operator[](int dimension);

16.

size_t operator[](int dimension) const;

17.
18.

size_t size() const;

19.
20.

// OP は +, -, *, /, %, <<, >>, &, |, ^, &&, ||, <, >, <=, >= です21.

friend range operatorOP(const range& lhs, const range& rhs) { /* ... */ }218 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
22.

friend range operatorOP(const range& lhs, const size_t& rhs) { /* ... */ }

23.
24.

// OP は +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^= です25.

friend range& operatorOP(range& lhs, const range& rhs) { /* ... */ }26.

friend range& operatorOP(range& lhs, const size_t& rhs) { /* ... */ }

27.
28.

// OP は +, -, *, /, %, <<, >>, &, |, ^, &&, ||, <, >, <=, >= です29.

friend range operatorOP(const size_t& lhs, const range& rhs) { /* ... */ }

30.
31.

// OP は単項の +, - です32.

friend range operatorOP(const range& rhs) { /* ... */ }

33.
34.

// OP はプリフィクス ++, -- です35.

friend range& operatorOP(range& rhs) { /* ... */ }

36.
37.

// OP はポストフィックス ++, -- です38.

friend range operatorOP(range& lhs, int) { /* ... */}

39.
40.

};

41.
42.

// デダクション・ガイド

43.

range(size_t) -> range<1>;44.

range(size_t, size_t) -> range<2>;45.

range(size_t, size_t, size_t) -> range<3>;

46.
47.

} // sycl

表 110. range クラス・テンプレートのコンストラクター
コンストラクター

説明range(size_t dim0)

値 dim0 で 1D range を作成します。テンプレート・パラメーターの Dimensions が 1 に等しい場合にのみ有効です。

range(size_t dim0, size_t dim1)

値 dim0 と dim1 で 2D range を作成します。テンプレート・パラ
メーターの Dimensions が 2 に等しい場合にのみ有効です。

range(size_t dim0, size_t dim1, size_t dim2)

値 dim0、dim1、および dim2 で 3D range を作成します。テンプ
レート・パラメーターの Dimensions が 3 に等しい場合にのみ有効です。

表 111. range クラス・テンプレートのメンバー関数
メンバー関数説明

size_t get(int dimension) const

指定された range 次元の値を返します。

size_t& operator[](int dimension)指定された range 次元の lvalue を返します。

size_t operator[](int dimension) const

指定された range 次元の値を返します。

第 4 章 SYCL プログラミング・インターフェイス | 219

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

size_t size() const

dimension0*…*dimensionN で計算された range のサイズを返します。

表 112. SYCL range クラス・テンプレートの隠匿されたフレンド関数
隠匿されたフレンド関数

説明

range operatorOP(const range& lhs, const range& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
lhs range と同じ次元の SYCL range クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL range インスタンスの各要素は、lhs range の各要素と rhs range 各要素間の要
素ごとの OP オペレーターの結果です。オペレーターが bool を返すと、結果は size_t にキャストされます。

range operatorOP(const range& lhs, const size_t& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
lhs range と同じ次元の SYCL range クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL range インスタンスの各要素は、この SYCL range の各要素と rhs size_t 各要素
間の要素ごとの OP オペレーターの結果です。オペレーターがbool を返すと、結果は size_t にキャストされます。

range& operatorOP(range& lhs, const range& rhs)

OP は次のいずれかです: +=、 -=、*=、 /=、 %=、<<=、>>=、&=、|=、^=。
lhs range のインスタンスの各要素に、lhs range の各要素と rhs
range の各要素間の要素ごとの OP オペレーターの結果を割り当てて、lhs range を返します。オペレーターが bool を返すと、結果は size_t にキャストされます。

range& operatorOP(range& lhs, const size_t& rhs)

OP は次のいずれかです: +=、 -=、*=、 /=、 %=、<<=、>>=、&=、|=、^=。
lhs range のインスタンスの各要素に、lhs range の各要素と rhs
size_t 間の要素ごとの OP オペレーターの結果を割り当てて、lhs
range を返します。オペレーターが bool を返すと、結果は size_tにキャストされます。

range operatorOP(const size_t& lhs, const range& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
rhs SYCL range と同じ次元の SYCL range クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL range イ
ンスタンスの各要素は、lhs size_t と rhs SYCL range の各要素
間の要素ごとの OP オペレーターの結果です。オペレーターがbool を返すと、結果は size_t にキャストされます。

220 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現隠匿されたフレンド関数

説明

range operatorOP(const range& rhs)

OP は単項 +、単項 - です。
rhs SYCL range と同じ次元の SYCL range クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL range イ
ンスタンスの各要素は、rhs SYCL range の要素ごとの OP オペ
レーターの結果です。

range& operatorOP(range& rhs)

OP はプリフィクス ++、プリフィクス -- です。
rhs range インスタンスの各要素に、rhs range の各要素に対する要素ごとの OP オペレーターの結果を割り当てて、この rangeを返します。

range operatorOP(range& lhs, int)

OP はポストフィックス ++、ポストフィックス -- です。
lhs range をコピーします。lhs range インスタンスの各要素に、
lhs range の各要素に対する要素ごとの OP オペレーターの結果を割り当てます。そして、range の最初のコピーを返します。

4.9.1.2. nd_range class1.

namespace sycl {2.

template <int Dimensions = 1>

3.

class nd_range {4.

public:5.
6.

/* -- 共通インターフェイスのメンバー -- */7.
8.

// オフセットは SYCL2020 では非推奨です9.

nd_range(range<Dimensions> globalSize, range<Dimensions> localSize,10.

id<Dimensions> offset = id<Dimensions>());

11.
12.

range<Dimensions> get_global_range() const;

13.

range<Dimensions> get_local_range() const;

14.

range<Dimensions> get_group_range() const;

15.

id<Dimensions> get_offset() const; // SYCL 2020 では非推奨

16.

}；

17.

} // namespace sycl

nd_range<int Dimensions> は、work-group とディスパッチ全体の両方の反復ドメインを定義します。これを定義するため、
nd_range は、カーネルが実行されるレンジ全体と、それぞれの work-group のレンジの 2 つで構成されます。
SYCL nd_range クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL nd_range クラスの概要を以下に示します。SYCL nd_range クラスのコンストラクターとメンバー関数を表 113 と表 114 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。

第 4 章 SYCL プログラミング・インターフェイス | 221

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
表 113. nd_range クラスのコンストラクター
コンストラクター

説明

nd_range<Dimensions>(

ローカルおよびグローバル構成レンジから nd_range を作成しrange<Dimensions> globalSize,

ます。オプションのオフセットは、SYCL 2020 では非推奨になり

range<Dimensions> localSize)ました。オフセットが指定されない限り、デフォルトはオフセット

id<Dimensions> offset = id<Dimensions>())

なしです。

表 114. nd_range クラスのメンバー関数
メンバー関数説明

range<Dimensions> get_global_range() const

構成要素のグローバルレンジを返します。

range<Dimensions> get_local_range() const

構成要素のローカルレンジを返します。

range<Dimensions> get_group_range() const

各次元のグループ数を表すレンジを返します。このレンジは、構築時に提供される globalSize/localSize から生じます。

id<Dimensions> get_offset() const

SYCL 2020 では非推奨です。構成要素のオフセットを返します。

// SYCL 2020 では非推奨

4.9.1.3. id クラス
id<int Dimensions> は、グローバルまたはローカル range の id を示す次元のベクトルです。同じランクアクセサーのインデックスとして使用できます。添字オペレーター (operator[](n)) は、コンポーネント n を size_t として返します。
SYCL id クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL id クラスの概要を以下に示します。SYCL id クラスのコンストラクター、メンバー関数、および非メンバー関数については、表116、表 117 および表 118 をご覧ください。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
1.

namespace sycl {2.

template <int Dimensions = 1>

3.

class id {4.

public:

5.

id();

6.
7.

/* 次のコンストラクターは、id クラスの特殊化

8.

* でのみ使用できます (Dimensions==1) */9.

id(size_t dim0);10.

/* 次のコンストラクターは、id クラスの特殊化

11.

* でのみ使用できます (Dimensions==2) */12.

id(size_t dim0, size_t dim1);

13.

/* 次のコンストラクターは、id クラスの特殊化

14.

* でのみ使用できます (Dimensions==3) */15.

id(size_t dim0, size_t dim1, size_t dim2);

16.
17.

/* -- 共通インターフェイスのメンバー -- */222 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
18.
19.

id(const range<Dimensions>& range);20.

id(const item<Dimensions>& item);

21.
22.

size_t get(int dimension) const;

23.

size_t& operator[](int dimension);24.

size_t operator[](int dimension) const;

25.
26.

/* Dimensions == 1 のときのみ利用可能 */27.

operator size_t() const; 28

28.
29.

// OP は+, -, *, /, %, <<, >>, &, |, ^, &&, ||, <, >, <=, >= です30.

friend id operatorOP(const id& lhs, const id& rhs) { /* ... */ }31.

friend id operatorOP(const id& lhs, const size_t& rhs) { /* ... */ }

32.
33.

// OP は +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^= です34.

friend id& operatorOP(id& lhs, const id& rhs) { /* ... */ }35.

friend id& operatorOP(id& lhs, const size_t& rhs) { /* ... */ }

36.
37.

// OP は +, -, *, /, %, <<, >>, &, |, ^, &&, ||, <, >, <=, >= です。

38.

friend id operatorOP(const size_t& lhs, const id& rhs) { /* ... */ }

39.
40.

// OP は単項の +, - です41.

friend id operatorOP(const id& rhs) { /* ... */ }

42.
43.

// OP はプリフィクス ++, -- です44.

friend id& operatorOP(id& rhs) { /* ... */ }

45.
46.

// OP はポストフィックス ++, -- です47.

friend id operatorOP(id& lhs, int) { /* ... */ }

48.
49.

};

50.
51.

// デダクション・ガイド

52.

id(size_t) -> id<1>;53.

id(size_t, size_t) -> id<2>;

54.

id(size_t, size_t, size_t) -> id<3>;

55.
56.

} // namespace sycl

表 115. id クラス・テンプレートのコンストラクター
コンストラクター

説明

id()

各次元の値が 0 の SYCL id を作成します。

id(size_t dim0)

値 dim0 で 1D id を作成します。テンプレート・パラメーターのDimensions が 1 に等しい場合にのみ有効です。

id(size_t dim0, size_t dim1)

値 dim0、dim1 で 2D id を作成します。テンプレート・パラメー
ターの Dimensions が 2 に等しい場合にのみ有効です。

第 4 章 SYCL プログラミング・インターフェイス | 223

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

コンストラクター説明id(size_t dim0, size_t dim1, size_t dim2)

値 dim0、dim1、dim2 で 3D id を作成します。テンプレート・パラ
メーターの Dimensions が 3 に等しい場合にのみ有効です。

id(const range<Dimensions>& range)

range の次元から id を作成します。

id(const item<Dimensions>& item)

item.get_id() から id を作成します。

表 116. id クラス・テンプレートのメンバー関数
メンバー関数説明

size_t get(int dimension) const

次元 Dimensions の id 値を返します。

size_t& operator[](int dimension)

id オブジェクトの要求された次元への参照を返します。

size_t operator[](int dimension) const

id オブジェクトの要求された次元の値を返します。

operator size_t() const

Dimensions == 1 の場合にのみ利用できます。
get(0) と同じ値を返します。

表 117. id クラス・テンプレートの隠匿されたフレンド関数
隠匿されたフレンド関数

説明

id operatorOP(const id& lhs, const id& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
lhs id と同じ次元の SYCL id クラス・テンプレートの新しいインス
タンスを構築して返します。新しい SYCL id インスタンスの各要
素は、lhs id の各要素と rhs id の各要素間の要素ごとの OP オペ
レーターの結果です。オペレーターが bool 値を返すと、結果は
size_t にキャストされます。

id operatorOP(const id& lhs, const size_t& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
lhs id と同じ SYCL id クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL id インスタンスの各要素は、
lhs id の各要素と rhs size_t 各要素間の要素ごとの OP オペレー
ターの結果です。オペレーターが bool を返すと結果は size_t にキャストされます。

224 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現隠匿されたフレンド関数

説明

id& operatorOP(id& lhs, const id& rhs)

OP は次のいずれかです: +=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=。
lhs id のインスタンスの各要素に、lhs id の各要素と rhs id の各要素間の要素ごとの OP オペレーターの結果を割り当てて、lhs idを返します。オペレーターが bool を返すと結果は size_t にキャストされます。

id& operatorOP(id& lhs, const size_t& rhs)

OP は次のいずれかです: +=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=。
lhs id のインスタンスの各要素に lhs id の各要素と rhs size_t の各要素間の OP オペレーターの結果を割り当てて、lhs id を返します。オペレーターが bool を返すと結果は size_t にキャストされます。

id operatorOP(const size_t& lhs, const id& rhs)

OP は次のいずれかです: +、-、*、/、%、<<、>>、&、|、^、&&、||、<、>、<=、>=。
rhs SYCL id と同じ次元の SYCL id クラス・テンプレートの新しいインスタンスを構築して返します。新しい SYCL id インスタンスの各要素は、lhs size_t と rhs SYCL id の各要素間の要素ごとの OP
オペレーターの結果です。オペレーターが bool を返すと結果は
size_t にキャストされます。

id operatorOP(const id& rhs)

OP は単項 +、単項 - です。
rhs SYCL id と同じ次元の SYCL id クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL id インスタンスの各要素は、rhs SYCL id の要素ごとの OP オペレーターの結果です。

id& operatorOP(id& rhs)

OP はプリフィクス ++、プリフィクス -- です。
rhs id インスタンスの各要素に、rhs id の各要素に対する要素ごとの OP オペレーターの結果を割り当てて、このid を返します。

id operatorOP(id& lhs, int)

OP はポストフィックス ++、ポストフィックス -- です。
lhs id のコピーを作成します。lhs id インスタンスの各要素に、lhs
id の各要素に対する要素ごとの OP オペレーターの結果を割り当てて、id の最初のコピーを返します。

4.9.1.4. item クラス
item は、range 内のそれぞれの位置で実行される関数オブジェクトのインスタンスを識別します。これは、parallel_for 呼び出しに渡されるか、h_item のメンバー関数によって返されます。work-item で利用可能なレンジ値とそのレンジ内の ID を識別する情報をカプセ
ル化します。parallel_for に適用される場合は、オプションでレンジのオフセットを提供できますが、これは SYCL2020 では非推奨で第 4 章 SYCL プログラミング・インターフェイス | 225

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現あることに注意してください。item クラスのインスタンスは、ユーザーが作成することはできません。ランタイムによって関数オブジェク
トの各インスタンスに渡されます。
SYCL item クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL item クラスの概要を以下に示します。SYCL item クラスのメンバー関数を表 118 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
1.

namespace sycl {2.

template <int Dimensions = 1, bool WithOffset = true>3.

class item {4.

public:5.

item() = delete;6.
7.

/* -- 共通インターフェイスのメンバー -- */8.
9.

id<Dimensions> get_id() const;

10.
11.

size_t get_id(int dimension) const;

12.
13.

size_t operator[](int dimension) const;

14.
15.

range<Dimensions> get_range() const;

16.
17.

size_t get_range(int dimension) const;

18.
19.

// SYCL 2020 では非推奨

20.

// WithOffset が true の場合にのみ利用可能

21.

id<Dimensions> get_offset() const;

22.
23.

// WithOffset が false の場合にのみ利用可能

24.

operator item<Dimensions, true>() const;

25.
26.

/* Dimensions == 1 のときのみ利用可能 */27.

operator size_t() const;

28.
29.

size_t get_linear_id() const;

30.

};

31.

} // namespace sycl

表 118. item クラスのメンバー関数
メンバー関数説明

id<Dimensions> get_id() const

反復空間で work-item の位置を示す構成 id を返します。

size_t get_id(int dimension) const

get_id()[dimension] と同じ値を返します。

size_t operator[](int dimension) const

get_id(dimension) と同じ値を返します。

range<Dimensions> get_range() const

item 値のレンジの次元を示す range を返します。

226 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

size_t get_range(int dimension) const

get_range().get(dimension) と同じ値を返します。

id<Dimensions> get_offset() const

SYCL 2020 では非推奨です。parallel_for に適用されランライム// SYCL 2020 では非推奨

によって work-item のグローバル ID に追加される、n 次元のオフセットを表す id を返します (この item がグローバルレンジを表現する場合)。オフセットを持たない item から変換された場合、これは常にすべて 0 値の id を返します。
このメンバー関数は、with_offset が true の場合にのみ使用できます。

operator item<Dimensions, true>() const

次のときにのみ利用可能:
with_offset == false
オブジェクトが保持するのと同じ情報を示す item を返しますが、それには 0 に設定されたオフセットも含まれます。この変換によって、ユーザーはオフセットを予測し、オフセットを持たない
item を提供するコードをシームレスに記述できます。

operator size_t() const

Dimensions == 1 の場合にのみ利用できます。
get(0) と同じ値を返します。

size_t get_linear_id() const

id を線形インデックス値として返します。多次元インデックスから
線形アドレスを計算するには、3.11.1 節の説明に従います。

4.9.1.5. nd_item クラス
nd_item<int Dimensions> は、parallel_for 呼び出しに渡される nd_range<int Dimensions> の各ポイントで実行される関数オブジェクトのインスタンスを識別します。work-item のローカルおよびグローバル id、work-group id を識別するための情報をカプセル化し、group と sub­group クラスへのアクセスを提供します。nd_item<int Dimensions> のインスタンスは、ユーザーが作成することはできません。ランタイムによって関数オブジェクトの各インスタンスに渡されます。
SYCL nd_item クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL nd_item クラスの概要を以下に示します。SYCL nd_item クラスのメンバー関数を表 119 に示します。追加の共通特殊メンバー
関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
nd_item クラスの % インターフェイス
1.

namespace sycl {2.

template <int Dimensions = 1>

3.

class nd_item {4.
5.

public:nd_item() = delete;6.
7.

/* -- 共通インターフェイスのメンバー -- */8.
9.

id<Dimensions> get_global_id() const;

第 4 章 SYCL プログラミング・インターフェイス | 227

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
10.
11.

size_t get_global_id(int dimension) const;

12.
13.

size_t get_global_linear_id() const;

14.
15.

id<Dimensions> get_local_id() const;

16.
17.

size_t get_local_id(int dimension) const;

18.
19.

size_t get_local_linear_id() const;

20.
21.

group<Dimensions> get_group() const;

22.
23.

sub_group get_sub_group() const;

24.
25.

size_t get_group(int dimension) const;

26.
27.

size_t get_group_linear_id() const;

28.
29.

range<Dimensions> get_group_range() const;

30.
31.

size_t get_group_range(int dimension) const;

32.
33.

range<Dimensions> get_global_range() const;

34.
35.

size_t get_global_range(int dimension) const;

36.
37.

range<Dimensions> get_local_range() const;

38.
39.

size_t get_local_range(int dimension) const;

40.
41.

// SYCL 2020 では非推奨

42.

id<Dimensions> get_offset() const;

43.
44.

nd_range<Dimensions> get_nd_range() const;

45.
46.

template <typename DataT>

47.

device_event async_work_group_copy(decorated_local_ptr<DataT> dest,48.

decorated_global_ptr<DataT> src, size_t NumElements) const;

49.
50.

template <typename DataT>

51.

device_event async_work_group_copy(decorated_global_ptr<DataT> dest,

52.

decorated_local_ptr<DataT> src, size_t NumElements) const;

53.
54.

template <typename DataT>

55.

device_event async_work_group_copy(decorated_local_ptr<DataT> dest,

56.

decorated_global_ptr<DataT> src, size_t NumElements, size_t srcStride) const;

57.
58.

template <typename DataT>

59.

device_event async_work_group_copy(decorated_global_ptr<DataT> dest,

60.

decorated_local_ptr<DataT> src, size_t NumElements, size_t destStride) const;

61.

228 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
62.

template <typename... EventTN>

63.

void wait_for(EventTN... events) const;

64.

};

65.

} // namespace sycl

表 119. nd_item クラスのメンバー関数
メンバー関数説明

id<Dimensions> get_global_id() const

グローバル反復空間での work-item の位置を示すグローバルidを返します。

size_t get_global_id(int dimension) const

指定された Dimensions の nd-range 内の work-item の位置を示すグローバルid の構成要素を返します。

size_t get_global_linear_id() const

グローバル反復空間での work-item 位置を示す構成グローバル
id を線形インデックス値として返します。線形アドレスは、最初にオフセットを減算してから 3.11.1 節で説明する手順に従って、多次元インデックスから計算されます。

id<Dimensions> get_local_id() const

現在の work-group 内の work-item の位置を示すローカルid 構
成要素を返します。

size_t get_local_id(int dimension) const

指定された Dimensions 内の現在の work-group の work-itemの位置を示すローカルid 構成要素を返します。

size_t get_local_linear_id() const

現在の work-group 内の work-item 位置を示すローカルid 構
成要素を線形インデックス値として返します。線形アドレスは、
3.11.1 節で説明する手順に従って多次元インデックスから計算されます。

group<Dimensions> get_group() const

work-group 構成要素を返します。group は、nd-range 全体でのwork-group の位置を示します。

sub_group get_sub_group() const

work-item が属する sub-group を示す sub_group を返します。

size_t get_group(int dimension) const

指定された dimension の nd_range 全体での work-group の位置を示すグループ id の構成要素を返します。

size_t get_group_linear_id() const

グループ id を線形インデックス値として返します。多次元イン
デックスから線形アドレスを計算するには、3.11.1 節の説明に従います。

range<Dimensions> get_group_range() const

反復空間内の work-group 数を返します。

size_t get_group_range(int dimension) const

反復空間の dimension の work-group 数を返します。

range<Dimensions> get_global_range() const

グローバル反復空間の次元を示す range を返します。

第 4 章 SYCL プログラミング・インターフェイス | 229

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

size_t get_global_range(int dimension) const

get_global_range().get(dimension) と同じ値を返します。

range<Dimensions> get_local_range() const

現在の work-group の次元を示す range を返します。

size_t get_local_range(int dimension) const

get_local_range().get(dimension) と同じ値を返します。

id<Dimensions> get_offset() const

SYCL 2020 では非推奨です。nd_range のコンストラクターに提// SYCL 2020 では非推奨供され、ランタイムによってそれぞれの work-item の global id に追加される n 次元のオフセットを示す id を返します。

nd_range<Dimensions> get_nd_range() const

現在の実行の nd_range を返します。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素をソースポインター src かdecorated_local_ptr<DataT> dest,

らデスティネーション・ポインター dest に非同期にコピーして、コ

decorated_global_ptr <DataT> src,

ピーの完了を待機するのに使用する SYCL device_event を返し

size_t NumElements) const

ます。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素をソースポインター src かdecorated_global_ptr<DataT> dest,

らデスティネーション・ポインター dest に非同期にコピーして、コ

decorated_local_ptr<DataT> src,

ピーの完了を待機するのに使用する SYCL device_event を返し

size_t NumElements) const

ます。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素を、srcStride で指定されdecorated_local_ptr<DataT> dest,

るソースストライドでソースポインター src からデスティネーショ

decorated_global_ptr<DataT> src,

ン・ポインター dest に非同期にコピーして、コピーの完了を待機

size_t NumElements, size_t srcStride) const

するのに使用する SYCL device_event を返します。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素を、destStride で指定さdecorated_global_ptr<DataT> dest,

れるデスティネーション・ストライドでソースポインター src から

decorated_local_ptr<DataT> src,

デスティネーション・ポインター dest に非同期にコピーして、コ

size_t NumElements, size_t destStride) const

ピーの完了を待機するのに使用する SYCL device_event を返します。

template <typename... EventTN>
void wait_for(EventTN... events) const

許容される eventTN のタイプは device_event です。それぞれのdevice_event に関連付けられた非同期操作が完了するのを待機します。

4.9.1.6. h_item クラス
h_item<int Dimensions> は、parallel_for_work_item 呼び出し、または parallel_for_work_item 呼び出しに range が渡されない場 合 、 対 応 す る parallel_for_work_group に 渡 さ れ る ロ ー カ ル range<int Dimensions> の 各 ポ イ ン ト で 実 行 さ れ るgroup::parallel_for_work_item 関数オブジェクトのインスタンスを識別します。

230 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
これは、parallel_for_work_group (物理 id) に与えられた論理ローカルレンジ内の work-item の論値ローカル item に従って、workitem のローカルおよびグローバル item を識別するのに十分な情報をカプセル化します。戻り値であるすべての item オブジェクトはオフセットなしです。h_item<int Dimensions> クラスのインスタンスは、ユーザーが作成することはできません。ランタイムによって関数オブジェクトの各インスタンスに渡されます。
SYCL nd_item クラス・テンプレートは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL h_item クラスの概要を以下に示します。SYCL h_item クラスのメンバー関数を表 120 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
1.

namespace sycl {2.

template <int Dimensions>3.

class h_item {4.

public:5.

h_item() = delete;6.
7.

/* -- 共通インターフェイスのメンバー -- */8.
9.

item<Dimensions, false> get_global() const;

10.
11.

item<Dimensions, false> get_local() const;

12.
13.

item<Dimensions, false> get_logical_local() const;

14.
15.

item<Dimensions, false> get_physical_local() const;

16.
17.

range<Dimensions> get_global_range() const;

18.
19.

size_t get_global_range(int dimension) const;

20.
21.

id<Dimensions> get_global_id() const;

22.
23.

size_t get_global_id(int dimension) const;

24.
25.

range<Dimensions> get_local_range() const;

26.
27.

size_t get_local_range(int dimension) const;

28.
29.

id<Dimensions> get_local_id() const;

30.
31.

size_t get_local_id(int dimension) const;

32.
33.

range<Dimensions> get_logical_local_range() const;

34.
35.

size_t get_logical_local_range(int dimension) const;

36.
37.

id<Dimensions> get_logical_local_id() const;

38.
39.

size_t get_logical_local_id(int dimension) const;

40.
41.

range<Dimensions> get_physical_local_range() const;

42.

第 4 章 SYCL プログラミング・インターフェイス | 231

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
43.

size_t get_physical_local_range(int dimension) const;

44.
45.

id<Dimensions> get_physical_local_id() const;

46.
47.

size_t get_physical_local_id(int dimension) const;

48.
49.

};

50.

} // namespace sycl

表 120. h_item クラスのメンバー関数
メンバー関数説明

item<Dimensions, false> get_global() const

カーネル起動時に提供されるグローバル反復空間での workitem の位置を示す構成グローバル item を返します。

item<Dimensions, false> get_local() const

get_logical_local() と同じ値を返します。

item<Dimensions, false> get_logical_local() const

group::parallel_for_work_item の呼び出し時に与えられた、
ローカル反復空間内の論理ローカル item の work-item の位置の構成要素を返します。
group::parallel_for_work_item が論理ローカルレンジなしで呼び出されると、メンバー関数は物理ローカル item を返します。
物理 id は、次のように論理 id と物理レンジの整数除算から余りを取得することで計算できます。
get_logical_local().get() % get_physical_local.get_range()== get_physical_local().get()item<Dimensions, false> get_physical_local() const

カーネルの呼び出し時にユーザーまたはランタイムによって与えられた、ローカル反復空間内の物理ローカル item の work-itemの位置の構成要素を返します。

range<Dimensions> get_global_range() const

get_global().get_range() と同じ値を返します。

size_t get_global_range(int dimension) const

get_global().get_range(dimension) と同じ値を返します。

id<Dimensions> get_global_id() const

get_global().get_id() と同じ値を返します。

size_t get_global_id(int dimension) const

get_global().get_id(dimension) と同じ値を返します。

range<Dimensions> get_local_range() const

get_local().get_range() と同じ値を返します。

size_t get_local_range(int dimension) const

get_local().get_range(dimension) と同じ値を返します。

id<Dimensions> get_local_id() const

get_local().get_id() と同じ値を返します。

size_t get_local_id(int dimension) const

get_local().get_id(dimension) と同じ値を返します。

232 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

range<Dimensions> get_logical_local_range() const

get_logical_local().get_range() と同じ値を返します。

size_t get_logical_local_range(int dimension) const

get_logical_local().get_range(dimension) と 同 じ 値 を 返 します。

id<Dimensions> get_logical_local_id() const

get_logical_local().get_id() と同じ値を返します。

size_t get_logical_local_id(int dimension) const

get_logical_local().get_id(dimension) と同じ値を返します。

range<Dimensions> get_physical_local_range() const

get_physical_local().get_range() と同じ値を返します。

size_t get_physical_local_range(int dimension) const

get_physical_local().get_range(dimension) と同じ値を返します。

id<Dimensions> get_physical_local_id() const

get_physical_local().get_id() と同じ値を返します。

size_t get_physical_local_id(int dimension) const

get_physical_local().get_id(dimension) と同じ値を返します。

4.9.1.7. group クラス
group<int Dimensions> は、並列実行内で特定の sub-group を表現するため必要なすべての機能をカプセル化します。ユーザーが作成することはできません。
グループクラスに格納されているローカルレンジは、オプションのパラメーターとして parallel_for_work_group に渡される際にプログラマーによって指定されるか、適切な work-group サイズを選択する際にランタイムによって与えられます。これにより開発者は、
parallel_for_work_item ループの抽象化された反復レンジから実行中の各 work-group でアクティブな同時 work-item の数を知ることができます。
SYCL group クラス・テンプレートは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL group クラスの概要を以下に示します。SYCL group クラスのメンバー関数を表 121 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
1.

namespace sycl {2.

template <int Dimensions = 1>

3.

class group {4.

public:5.
6.

using id_type = id<Dimensions>;

7.

using range_type = range<Dimensions>;

8.

using linear_id_type = size_t;

9.

static constexpr int Dimensions = Dimensions;10.

static constexpr memory_scope fence_scope = memory_scope::work_group;

11.
12.

/* -- 共通インターフェイスのメンバー -- */

13.
14.

id<Dimensions> get_group_id() const;

第 4 章 SYCL プログラミング・インターフェイス | 233

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
15.
16.

size_t get_group_id(int dimension) const;

17.
18.

id<Dimensions> get_local_id() const;

19.
20.

size_t get_local_id(int dimension) const;

21.
22.

range<Dimensions> get_local_range() const;

23.
24.

size_t get_local_range(int dimension) const;

25.
26.

range<Dimensions> get_group_range() const;

27.
28.

size_t get_group_range(int dimension) const;

29.
30.

range<Dimensions> get_max_local_range() const;

31.
32.

size_t operator[](int dimension) const;

33.
34.

size_t get_group_linear_id() const;

35.
36.

size_t get_local_linear_id() const;

37.
38.

size_t get_group_linear_range() const;

39.
40.

size_t get_local_linear_range() const;

41.
42.

bool leader() const;

43.
44.

template<typename WorkItemFunctionT>

45.

void parallel_for_work_item(const WorkItemFunctionT& func) const;

46.
47.

template<typename WorkItemFunctionT>48.

void parallel_for_work_item(range<Dimensions> logicalRange,

49.

const WorkItemFunctionT& func) const;

50.
51.

template <typename DataT>

52.

device_event async_work_group_copy(decorated_local_ptr<DataT> dest,

53.

decorated_global_ptr<DataT> src, size_t NumElements) const;

54.
55.

template <typename DataT>

56.

device_event async_work_group_copy(decorated_global_ptr<DataT> dest,

57.

decorated_local_ptr<DataT> src, size_t NumElements) const;

58.
59.

template <typename DataT>

60.

device_event async_work_group_copy(decorated_local_ptr<DataT> dest,

61.

decorated_global_ptr<DataT> src, size_t NumElements, size_t srcStride) const;

62.
63.

template <typename DataT>

64.

device_event async_work_group_copy(decorated_global_ptr<DataT> dest,

65.

decorated_local_ptr<DataT> src, size_t NumElements, size_t destStride) const;

66.

234 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
67.

template <typename... EventTN>

68.

void wait_for(EventTN... events) const;

69.

};

70.

} // namespace sycl

表 121. group クラスのメンバー関数
メンバー関数説明

id<Dimensions> get_group_id() const

すべての次元の nd-range 内の work-group のインデックスを示
す id を返します。

size_t get_group_id(int dimension) const

get_group_id()[dimension] と同じ値を返します。

id<Dimensions> get_local_id() const

work-group 内の呼び出し元である work-item の位置を示す
SYCL id を返します。
このメンバー関数が parallel_for_work_item コンテキストから呼び出されると動作は未定義となります。

size_t get_local_id(int dimension) const

指定された次元の work-group 内にある呼び出し元の workitem の位置を返します。
このメンバー関数が parallel_for_work_item コンテキストから呼び出されると動作は未定義となります。

range<Dimensions> get_local_range() const

ローカルレンジのすべての次元を示す SYCL range を返します。
このローカルレンジは、プログラマーによって指定されるか、
SYCL ランタイムによって選択される可能性があります。

size_t get_local_range(int dimension) const

dimension パラメーターで指定されるローカルレンジの次元を返します。

range<Dimensions> get_group_range() const

nd_range 内の work-group 数を示す range を返します。

size_t get_group_range(int dimension) const

グループレンジの構成要素から要素の dimension を返します。

size_t operator[](int dimension) const

get_group_id(dimension) と同じ値を返します。

range<Dimensions> get_max_local_range() const

nd_range の work-group 内 の work-item の 最 大 数 を 示 すrange を返します。

size_t get_group_linear_id() const

work-group id の線形化バージョンを取得します。多次元イン
デックスから線形 work-group id を計算するには、3.11.1 節の説
明に従います。

size_t get_group_linear_range() const

nd_range 内の work-group の合計数を返します。

第 4 章 SYCL プログラミング・インターフェイス | 235

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

size_t get_local_linear_id() const

呼び出し元の work-item のローカルid の線形化バージョンを取得します。多次元インデックスから線形ローカルid を計算するには、3.11.1 節の説明に従います。
このメンバー関数が parallel_for_work_item コンテキストから呼び出されると動作は未定義となります。

size_t get_local_linear_range() const

すべての work-group の work-item の合計数を返します。

bool leader() const

呼び出し元の work-item が work-group のリーダーである場合、
work-group 内の 1 つの work-item に対して true を返し、それ以外には false を返します。
work-group のリーダーは work-group の構築中に決定され、
work-group の存続期間中は不変です。work-group のリーダー
は、ローカル id が 0 の work-item であることが保証されます。

template <typename WorkItemFunctionT>
void parallel_for_work_item(const WorkItemFunctionT&func) const

この work-group の work-item を起動します。
func は、work-item の計算を表すパブリックメンバー関数 void
F::operator()(h_item<Dimensions>) を持つ関数オブジェクト・タイプです。
このメンバー関数は、parallel_for_work_group コンテキスト内
でのみ呼び出しできます。コードを実行する work-item 数が定義されていないため、work-group サイズを定義しない parallel_
for_work_group 形式内からこのメンバー関数を呼び出すと動作は未定義です。この形式の parallel_for_work_item は、workgroup のサイズを指定する parallel_for_work_group 形式内で呼び出されることが期待されます。

236 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename WorkItemFunctionT>

論理ローカルレンジを使用して、この work-group の work-item

void parallel_for_work_item(range<Dimensions>

を起動します。関数オブジェクト func は、カーネルがローカルレ

logicalRange, const WorkItemFunctionT& func) const

ンジとして logicalRange で起動されたように実行されます。新しいローカルレンジはエミュレートされますが、物理レンジと 1 対1 でマッピングされないこともあります。
logicalRange は新たに使用されるローカルレンジです。このレンジは、カーネル呼び出しで使用されるレンジよりも小さくても大きくてもかまいません。func は、work-item の計算を示すパブリックメンバー関数 void F::operator()(h_item<Dimensions>)を持つ関数オブジェクト・タイプです。
論理レンジは、カーネル内のすべての work-group で均一である
必要はないことに注意してください。例えば、論理レンジが同じ
カーネル呼び出し内の異なる work-group で異なる論理サイズ
を 実 行するよ うに、 work-group が 異 な るクエリ ー ( 例えば 、
group::get_linear_id) に依存することがあります。
このメンバー関数は、parallel_for_work_group コンテキスト内
でのみ呼び出しできます。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素をソースポインター src かdecorated_local_ptr<DataT> dest,

らデスティネーション・ポインター dest に非同期にコピーして、コ

decorated_global_ptr<DataT> src,

ピーの完了を待機するのに使用する SYCL device_event を返し

size_t NumElements) const

ます。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素をソースポインター src かdecorated_global_ptr<DataT> dest,

らデスティネーション・ポインター dest に非同期にコピーして、コ

decorated_local_ptr<DataT> src,

ピーの完了を待機するのに使用する SYCL device_event を返し

size_t NumElements) const

ます。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素を、srcStride で指定されdecorated_local_ptr<DataT> dest,

るソースストライドでソースポインター src からデスティネーショ

decorated_global_ptr<DataT> src,

ン・ポインター dest に非同期にコピーして、コピーの完了を待機

size_t NumElements, size_t srcStride) const

するのに使用する SYCL device_event を返します。

template <typename DataT>

許 可 さ れ る DataT の タ イ プ は ス カ ラ ー と ベ ク ト ル で す 。

device_event async_work_group_copy(

NumElements で指定される数の要素を、destStride で指定さdecorated_global_ptr<DataT> dest,

れるデスティネーション・ストライドでソースポインター src から

decorated_local_ptr<DataT> src,

デスティネーション・ポインター dest に非同期にコピーして、コ

size_t NumElements, size_t destStride) const

ピーの完了を待機するのに使用する SYCL device_event を返します。

第 4 章 SYCL プログラミング・インターフェイス | 237

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename... EventTN>許容される eventTN のタイプは device_event です。それぞれのvoid wait_for(EventTN... events) const

device_event に関連付けられた非同期操作が完了するのを待機します。

4.9.1.8. sub_group クラス
並列実行内で特定の sub-group を表現するため必要なすべての sub_group クラスをカプセル化します。ユーザーが作成することはできません。
SYCL sub_group クラスは、一般的な値渡しのセマンティクスを提供します (4.5.3 節を参照)。
SYCL sub_group クラスの概要を以下に示します。SYCL sub_group のメンバー関数を表 122 に示します。追加の共通特殊メンバー
関数と共通メンバー関数については、4.5.3 節の表 9 と表 10 を参照してください。
1.

namespace sycl {2.

class sub_group {3.

public:4.
5.

using id_type = id<1>;6.

using range_type = range<1>;7.

using linear_id_type = uint32_t;

8.

static constexpr int dimensions = 1;

9.

static constexpr memory_scope fence_scope = memory_scope::sub_group;

10.
11.

/* -- 共通インターフェイスのメンバー -- */

12.
13.

id<1> get_group_id() const;

14.
15.

id<1> get_local_id() const;

16.
17.

range<1> get_local_range() const;

18.
19.

range<1> get_group_range() const;

20.
21.

range<1> get_max_local_range() const;

22.
23.

uint32_t get_group_linear_id() const;

24.
25.

uint32_t get_local_linear_id() const;

26.
27.

uint32_t get_group_linear_range() const;

28.
29.

uint32_t get_local_linear_range() const;

30.
31.

bool leader() const;

32.
33.

};

34.

} // namespace sycl

238 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
表 122. sub_group クラスのメンバー関数
メンバー関数説明

id<1> get_group_id() const

work-group 内の sub-group のインデックスを示す id を返します。

id<1> get_local_id() const

sub-group 内の呼び出し元である work-item の位置を示す
SYCL id を返します。

range<1> get_local_range() const

現在の sub-group のサイズ示す range を返します。このサイズ
は、親 work-group 内の sub-group の位置と、sub-group が実装によって構築される方法によっては、get_max_local_range()が返す値よりも小さくなることがあります。

range<1> get_group_range() const

work-group 内の sub-group 数を示す range を返します。

range<1> get_max_local_range() const

実行中のカーネルの sub-group で許容される work-item の最大数を示す range を返します。この値は、プログラマーが属性を介して選択したか、デバイス・コンパイラーが選択した可能性があります。

uint32_t get_group_linear_id() const

get_group_id() と同等です。

uint32_t get_group_linear_range() const

get_group_range() と同等です。

uint32_t get_local_linear_id() const

get_local_id() と同等です。

uint32_t get_local_linear_range() const

get_local_range() と同等です。

bool leader() const

呼び出し元の work-item が sub-group のリーダーである場合、
sub-group 内の 1 つの work-item に対し true を返し、subgroup 内のほかのすべての work-item には false を返します。
sub-group のリーダーは sub-group の構築中に決定され、subgroup の存続期間中は不変です。sub-group のリーダーは、ローカル id が 0 の work-item であることが保証されます。

4.9.2. リダクション変数
リダクションに関連するすべての機能は、reducer クラスおよび reduction 関数によってキャプチャーされます。
次の例は、同一の入力値に対して 2 つのリダクションを同時に行い、バッファー内のすべての値の合計と最大値を計算するリダクショ
ン・カーネルの作成方法を示しています。parallel_for に渡されるリダクション変数では、reducer オブジェクトへの参照がパラメー
ターとしてカーネル関数に同じ順番で渡されます。
1.

buffer<int> valuesBuf { 1024 };

2.

{

3.

// 0, 1, 2, 3, ..., 1023 でホスト上のバッファーを初期化

4.

host_accessor a { valuesBuf };第 4 章 SYCL プログラミング・インターフェイス | 239

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
5.
6.

std::iota(a.begin(), a.end(), 0);
}

7.
8.

// リダクションの結果を取得する単一要素のバッファー9.

int sumResult = 0;10.

buffer<int> sumBuf { &sumResult, 1 };11.

int maxResult = 0;12.

buffer<int> maxBuf { &maxResult, 1 };

13.
14.

myQueue.submit([&](handler& cgh) {

15.
16.

// リダクションの入力値は標準アクセサーです17.

auto inputValues = valuesBuf.get_access<access_mode::read>(cgh);

18.
19.

// リダクションのセマンティクスで変数を記述する一時オブジェクトを作成

20.

auto sumReduction = reduction(sumBuf, cgh, plus<>());

21.

auto maxReduction = reduction(maxBuf, cgh, maximum<>());

22.
23.

// parallel_for は 2 つのリダクション操作を実行

24.

// リダクション変数ごとの実装は以下の通り:

25.

// - 対応するレデューサーを作成

26.

// - レデューサーの参照をパラメーターとしてラムダ関数に渡す

27.

cgh.parallel_for(range<1>{1024},

28.

sumReduction, maxReduction,

29.

[=](id<1> idx, auto& sum, auto& max) {30.

// plus<>() は += オペレーターに対応するため、sum は += または combine() を介して更新します31.

sum += inputValues[idx];

32.
33.

// maximum<>() には省略形のオペレーターがないため、max は combine() を介してのみ更新できます34.

max.combine(inputValues[idx]);

35.
36.

});
});

37.
38.

// sumBuf と maxBuf には、カーネルが終了するとリダクションの結果が含まれます

39.

assert(maxBuf.get_host_access()[0] == 1023 && sumBuf.get_host_access()[0] == 523776);

C++ コア言語で定義されているように、自明のコピー可能なすべてのタイプのリダクションがサポートされています。リダクション・オペ
レーターが非結合または非可換である場合、リダクションの動作は非決定的である可能性があります。複数のリダクションが同じ変数を参照している場合、もしくはリダクションの存続期間中にリダクション変数に直接アクセスする場合 (例えば、アクセサーや USM ポ
インターにより)、動作は未定義となります。
reduction 関数のオーバーロードには、id 値を受け取るものと受け取らないものがあります。アプリケーションが id 値を指定していな
くても、正しいリダクション計算を行うような実装が必要です。ただし、id 値がアプリケーションから与えられることを実装が理解でき
れば、さらに効率良い実装が可能です。標準の二項オペレーター (算術タイプの + など) は、パフォーマンスの低下を回避するため、正し
い id 値を実装で自動的に決定する必要があります。
実装がアキュムレーター・タイプと関数オブジェクト・タイプの特定の組み合わせ id 値を識別できる場合、値は known_identity 特性
クラスのメンバーとして定義されます。このメンバー値が存在するかどうかは、has_known_identity 特性クラスを使用して評価できます。
1.

template <typename BinaryOperation, typename AccumulatorT>2.

struct known_identity {240 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
3.
4.

static constexpr AccumulatorT value;
};

5.
6.

template <typename BinaryOperation, typename AccumulatorT>

7.

inline constexpr AccumulatorT known_identity_v = known_identity<BinaryOperation, AccumulatorT>::value;8.
9.

template <typename BinaryOperation, typename AccumulatorT>

10.

struct has_known_identity {

11.
12.

static constexpr bool value;
};

13.
14.

template <typename BinaryOperation, typename AccumulatorT>

15.

inline constexpr bool has_known_identity_v = has_known_identity<BinaryOperation, AccumulatorT>::value;

表 123 に示す部分的な特殊化ごとに、known_identity (既知の id) があり、表に示す値を保持しています。
表 123. sub_group クラスのメンバー関数
オペレーター

次のときにのみ利用可能

id

sycl::plus

std::is_arithmetic_v<AccumulatorT>

AccumulatorT{}

sycl::multiplies

std::is_arithmetic_v<AccumulatorT>

AccumulatorT{1}sycl::bit_and

std::is_integral_v<AccumulatorT>~AccumulatorT{}

sycl::bit_or

std::is_integral_v<AccumulatorT>

AccumulatorT{}

sycl::bit_xor

std::is_integral_v<AccumulatorT>

AccumulatorT{}

sycl::logical_and

std::is_same_v<std::remove_v_t<AccumulatorT>, bool>true

sycl::logical_or

std::is_same_v<std::remove_v_t<AccumulatorT>, bool>

false

sycl::minimum

std::is_integral_v<AccumulatorT>

std::numeric_limits<AccumulatorT>::max()sycl::minimum

sycl::maximum

std::is_floating_point_v<AccumulatorT> ||std::numeric_limits

std::is_same_v<std::remove_cv_t<AccumulatorT>, sycl::half><AccumulatorT>::infinity()

std::is_integral_v<AccumulatorT>

std::numeric_limits<AccumulatorT>::lowest()

sycl::maximum

std::is_floating_point_v<AccumulatorT> ||std::numeric_limits

std::is_same_v<std::remove_cv_t<AccumulatorT>, sycl::half><AccumulatorT>::infinity()

リダクション・インターフェイスは、コンパイル時にサイズが決定されるリダクション変数に限定されます。そのため、buffer と USM ポ
インター引数は、リダクション・インターフェイスによって単一の変数を記述するものとして解釈されます。span に関連付けられたリダ
クション操作は、配列のリダクションを表現します。サイズ N のリダクション配列は、N 個の独立したスカラー・リダクションを行うのと第 4 章 SYCL プログラミング・インターフェイス | 241

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
機能的に同等です。配列リダクションによって行われる組み合わせ操作は、span で記述される USM 割り当て範囲に制限され、その領域外にアクセスすると動作は未定義となります。

span は 1 次元であるため、現在、複数の次元で配列にリダクションを記述することはできません。これは、SYCL 仕様の将来のバージョンで変更される予定ですが、多次元 span の導入に依存します。

4.9.2.1. reduction インターフェイス
reduction インターフェイスは、リダクション変数、リダクション・オペレーター、およびオペレーターに関連付けられたオプションの id値を指定することでリダクション・セマンティクスを変数にアタッチするために使用されます。インターフェイスのオーバーロードを表124 に示します。reduction インターフェイスの戻り値は、未定義タイプの実装定義オブジェクトであり、4.9.2.3 節で説明するように、
適切な reducer タイプを構築するため parallel_for によって解釈されます。
実装は、作成する reducer オブジェクト内で、不特定数の一時変数を使用することがあります。id 値が reduction に提供されると、実装はその値で一時変数を初期化します。

一時変数の数は不定であるため、リダクション演算子に関連する id 値とは異なる id 値を与えると、予期しない結果を招くことがあります。

reduction インターフェイスが起動されるときに property::reduction::initialize_to_identity プロパティーが指定されない限り、リダ
クション変数の初期値はリダクション操作に反映されます。
リダクション変数は、カーネルが実行を終了するとリダクションの結果を反映するように更新されます。
1.

template <typename BufferT, typename BinaryOperation>2.

__unspecified__ reduction(BufferT vars, handler& cgh, BinaryOperation combiner,
const property_list& propList = {});

3.
4.

template <typename T, typename BinaryOperation>

5.

__unspecified__ reduction(T* var, BinaryOperation combiner,

6.

const property_list& propList = {});

7.
8.

template <typename T, typename Extent, typename BinaryOperation>

9.

__unspecified__ reduction(span<T, Extent> vars, BinaryOperation combiner,

10.

const property_list& propList = {});

11.
12.

/* has_known_identity<BinaryOperation, BufferT::value_type>::value が false の場合にのみ利用できます */13.

template <typename BufferT, typename BinaryOperation>

14.

__unspecified__ reduction(BufferT vars, handler& cgh,const BufferT::value_type& identity, BinaryOperation combiner,
const property_list& propList = {});

15.
16.

/* has_known_identity<BinaryOperation, T>::value が false の場合にのみ利用できます */17.

template <typename T, typename BinaryOperation>

18.

__unspecified__ reduction(T* var, const T& identity, BinaryOperation combiner,
const property_list& propList = {});

19.
20.

/* has_known_identity<BinaryOperation, T>::value が false の場合にのみ利用できます */242 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
21.

template <typename T, typename Extent, typename BinaryOperation>

22.

__unspecified__ reduction(span<T, Extent> vars, const T& identity, BinaryOperation combiner);

表 124. reduction インターフェイスのオーバーロード関数

説明

reduction<BufferT, BinaryOperation>(BufferT vars,

combiner で指定される組み合わせ操作を使用して、vars に記述

handler&cgh, BinaryOperation combiner, const

される変数のリダクションを表す未定義のオブジェクトを作成しproperty_list& propList ={})

ます。property_list のインスタンスを介して、ゼロ個以上のプロ
パティーを提供できます。vars バッファーのレンジが 1 でない場
合、errc::invalid エラーコードで例外をスローします。

reduction<T, BinaryOperation>(T* var,combiner で指定される組み合わせ操作を使用して、vars に記述

BinaryOperation combiner,

される変数のリダクションを表す未定義のオブジェクトを作成しconst property_list& propList ={})

ます。property_list のインスタンスを介して、ゼロ個以上のプロ
パティーを提供できます。

reduction<T, BinaryOperation>(span<T, Extent> vars,

Extent != sycl::dynamic_extent のときにのみ利用できます。

BinaryOperation combiner,

combiner で指定される組み合わせ操作を使用して、vars に記述

const property_list& propList ={})

される変数のリダクションを表す未定義のオブジェクトを作成します。property_list のインスタンスを介して、ゼロ個以上のプロ
パティーを提供できます。

reduction<BufferT, BinaryOperation>(BufferT vars,
handler& cgh,const BufferT::value_type& identity,
BinaryOperation combiner,
const property_list& propList = {})combiner で指定される組み合わせ操作を使用して、vars に記述される変数のリダクションを表す未定義のオブジェクトを作成します。identity の値は、不特定数の一時的なアキュムレーター変数を初期化するため実装で使用される場合があります。
combiner で指定される組み合わせ操作の identity 値以外を使用すると動作は未定義となります。property_list のインスタンス
を介して、ゼロ個以上のプロパティーを提供できます。vars バッ
ファーのレンジが 1 でない場合、errc::invalid エラーコードで例
外をスローします。

reduction<T, BinaryOperation>(T* var, const T& identity,

combiner で指定される組み合わせ操作を使用して、vars に記

BinaryOperation combiner,

述される変数のリダクションを表す未定義のオブジェクトを作成

const property_list& propList ={})

します。identity の値は、不特定数の一時的なアキュムレーター
変数を初期化するため実装で使用される場合があります。
combiner で指定される組み合わせ操作の identity 値以外を使用すると動作は未定義となります。property_list のインスタンス
を介して、ゼロ個以上のプロパティーを提供できます。

第 4 章 SYCL プログラミング・インターフェイス | 243

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

関数

説明

reduction<T, BinaryOperation>(span<T, Extent> vars,

Extent != sycl::dynamic_extent の場合にのみ利用できます。

const T& identity,

combiner で指定される組み合わせ操作を使用して、vars に記述

BinaryOperation combiner,

される変数のリダクションを表す未定義のオブジェクトを作成しconst property_list& propList ={})

ます。identity の値は、不特定数の一時的なアキュムレーター変数を初期化するため実装で使用される場合があります。
combiner で指定される組み合わせ操作の identity 値以外を使用すると動作は未定義となります。property_list のインスタンス
を介して、ゼロ個以上のプロパティーを提供できます。

4.9.2.2. リダクション・プロパティー
reduction インターフェイスを使用する際に提供できるプロパティーを表 125 に示します。
表 125. reduction インターフェイスでサポートされるプロパティー
プロパティー説明

property::reduction::initialize_to_identity

initialize_to_identity プ ロ パ テ ィ ー は 、 SYCL ラ ン タ イ ム がreduction 変数を関連するリダクション・オペレーターの id 値に初期化する必要がある要件を追加します。リダクション・オペレー
ターの id 値を認識できない場合、known_identity 特性によって決定されます。また、id 値が指定されておらず、known_identity
特性から id 値を判別できない場合、コンパイラーは診断を行います。このプロパティーが設定されている場合、reduction 変数の元の値はリダクションに含まれません。

リダクション・プロパティーのコンストラクターを表 126に示します。
表 126. reduction property クラスのコンストラクター
コンストラクター

説明

property::reduction::initialize_to_identity::initialize_to_iden initialize_to_identity プロパティー・インスタンスを構築します。
tity()

4.9.2.3. reducer クラス
reducer クラスは、SYCL カーネルの実行中に work-item とリダクション変数間のインターフェイスを定義し、ベースとなるリダクショ
ン変数へのアクセスを制限します。
リダクション変数の中間値は、カーネルの実行中に検証することはできません。また、リダクションで指定された組み合わせ以外の操作
で変数を更新することもできません。異なるレデューサーの組み合わせ順序や各レデューサーの値がいつどのように元のリダクション変数と組み合わされるかは不定です。
リダクション・アルゴリズムの特殊化をコンパイル時に有効にするため、reducer クラスの実装は表 127 と表 128 で定義される関数とオペレーターを除いて未定義です。そのため、開発者は reducer のテンプレート引数を直接指定するのではなく、カーネル関数が任意

244 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現の reducer タイプ変数への参照を受け入れられるようにジェネリック・プログラミングの手法を用意する必要があります。ラムダとして記述されるカーネルは auto& または auto&... を使用し、関数オブジェクトとして記述されるカーネルはテンプレート・パラメーターまたはテンプレート・パラメーター・パックを使用する必要があります。
実装では、カーネルで同時に実行される work-item が reducer の組み合わせ関数を並列に呼び出す安全性を保証する必要があります。安全であることが保障できる場合、レデューサー変数を自由に再利用できます (例えば、同じ計算ユニットにスケジュールされた
work-group 間で)。
reducer クラスのメンバー関数を表 127 に示します。表 128 に示すように、リダクション変数タイプと組み合わせ操作の特定の組み合わせでは、追加の省略オペレーターを使用できます。
1.

// 説明用途のみ

2.

template <typename T, typename BinaryOperation, int Dimensions, /* 未定義 */>3.

class reducer {4.

public;5.
6.

using valute_type = T;7.

using binary_operation = BinaryOperation;

8.

static constexpr int dimension = Dimensions;9.
10.

reducer(const reducer&) = delete;11.

reducer(reducer&&) = delete;

12.

reducer& operator=(const reducer&) = delete;

13.

reducer& operator=(reducer&&) = delete;

14.
15.

reducer();

16.
17.

/* Dimensions == 0 のときのみ利用可能 */18.

reducer& combine(const T& partial);

19.
20.

/* Dimensions > 0 のときのみ利用可能 */21.

__unspecified__ operator[](size_t index) const;

22.
23.

/* 識別子の値が明らかであるときにのみ利用可能 */24.

T identity() const;

25.
26.

/* Dimensions > 0 で

27.

* BinaryOperation == plus<> または BinaryOperation == plus<T> のときに利用可能 */28.

friend reducer& operator += (reducer&, const T&) { /* ... */ }

29.
30.

/* Dimensions > 0 で

31.

* BinaryOperation == multiplies<> または BinaryOperation == multiplies<T> のときに利用可能 */32.

friend reducer& operator *= (reducer&, const T&) { /* ... */ }

33.
34.

/* Dimensions > 0 で T が整数タイプ、および

35.

* BinaryOperation == bit_and<> または BinaryOperation == bit_and<T> のときに利用可能 */36.

friend reducer& operator &= (reducer&, const T&) { /* ... */ }

37.
38.

/* Dimensions > 0 で T が整数タイプ、および

39.

* BinaryOperation == bit_or<> または BinaryOperation == bit_or <T> のときに利用可能 */40.

friend reducer& operator |= (reducer&, const T&) { /* ... */ }41.

第 4 章 SYCL プログラミング・インターフェイス | 245

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
42.

/* Dimensions > 0 で T が整数タイプ、および

43.

* BinaryOperation == bit_xor<> または BinaryOperation == bit_xor <T> のときに利用可能 */44.

friend reducer& operator ^= (reducer&, const T&) { /* ... */ }

45.
46.

/* Dimensions > 0 で T が整数タイプ、T がブール値ではなく47.

* BinaryOperation == plus<> または BinaryOperation == plus<T> のときに利用可能 */48.

friend reducer& operator ++ (reducer&, const T&) { /* ... */ }

49.
50.

};

表 127. reducer クラスのメンバー関数
メンバー関数説明

reducer& combine(const T& partial) const

次のときにのみ利用可能: Dimensions == 0 の場合。partial 値を
この reducer に関連付けられたリダクション変数と組み合わせま
す。*this を返します。

__unspecified__ operator[](size_t index) const

次 の と き に の み 利 用 可 能 : Dimensions > 0 の 場 合 。 次 元 がDimensions-1 で、インデックス Dimensions が index に設定された SYCL id を含む、reducer と同じタイプの reducer 示す未定
義の中間インスタンスを返します。返される中間型は、そのタイプ(添字オペレーターを含む) に適した reducer クラスで定義されるすべてのメンバー関数とオペレーターを提供する必要があります。

T identity() const

この reducer に関連付けられている組み合わせ操作の id 値を返します。id 値が実装で認識される場合にのみ利用できます。

表 128. reducer クラスの隠匿された friend オペレーター
オペレーター説明

reducer& operator+=(reducer& accum, const T& partial)

accum.combine(partial) の呼び出しと同等です。
次のときにのみ利用可能:
Dimensions == 0 &&(std::is_same_v<BinaryOperation,plus<>> ||std::is_same_v<BinaryOperation, plus<T>>) の場合。

reducer& operator*=(reducer& accum, const T& partial)

accum.combine(partial) の呼び出しと同等です。
次のときにのみ利用可能:
Dimensions == 0 &&(std::is_same_v<BinaryOperation,multiplies<>> ||std::is_same_v<BinaryOperation,multiplies<T>>) の場合。

246 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

オペレーター説明

reducer& operator&=(reducer& accum, const T& partial)

accum.combine(partial) の呼び出しと同等です。整数タイプでのみ利用できます。
次のときにのみ利用可能:
Dimensions == 0 && is_integral_v<T> &&(std::is_same_v<BinaryOperation,bit_and<>> ||std::is_same_v<BinaryOperation,bit_and<T>>) の場合。

reducer& operator|=(reducer& accum, const T& partial)

accum.combine(partial) の呼び出しと同等です。整数タイプでのみ利用できます。
次のときにのみ利用可能:
Dimensions == 0 && is_integral_v<T> &&(std::is_same_v<BinaryOperation,bit_or<>> ||std::is_same_v<BinaryOperation, bit_or<T>>) の場合。

reducer& operator^=(reducer& accum, const T& partial)

accum.combine(partial) の呼び出しと同等です。整数タイプでのみ利用できます。
次のときにのみ利用可能:
Dimensions == 0 && is_integral_v<T> &&(std::is_same_v<BinaryOperation,bit_xor<>> ||std::is_same_v<BinaryOperation,bit_xor<T>>) の場合。

reducer& operator++(reducer& accum)

accum.combine(1) の呼び出しと同等です。整数タイプでのみ利用できます。
次のときにのみ利用可能:
Dimensions == 0 && std::is_integral_v<T>&& !std::is_same_v<T,bool> &&(std::is_same_v<BinaryOperation, plus<>> ||std::is_same_v<BinaryOperation,plus<T>>) の場合。

4.9.3. コマンドグループのスコープ
3.7.1 節で定義されるコマンド・グループ・スコープは、カーネル呼び出し、メモリーのコピー、またはホストタスクの実行など、単一のコ
マンドを実行できます。コマンド・グループ・スコープにコマンド関数の複数の呼び出しを静的に含めることは許可されますが、コマンドグループ関数のオブジェクトを一度実行すると、実行できるコマンドは 1 つだけになります。アプリケーションがこれに失敗した場
合、コマンドグループ関数オブジェクト (queue::submit など) は、errc::invalid エラーコードの同期例外をスローする必要があります。
コマンドを呼び出すステートメントは、カーネルの要件を定義するステートメントとともに、コマンドグループ関数オブジェクトを構成します。コマンドグループ関数オブジェクトは、コマンドグループのスコープで実行されるすべてのメンバー関数をカプセル化するコ
マンド・グループ・ハンドラー・クラスのインスタンスをパラメーターとして受け取ります。このスコープ内で定義されたメンバー関数とオブジェクトは、カーネルの実行や明示的なメモリー操作の要件を定義し、操作の実行準備ができているかを判断するため SYCL ラン
タイム で使用されます。コマンドグループ関数オブジェクト内のホストコード (通常は要件の設定) は、コマンドグループの送信呼び出
しから戻る前に一度だけ実行されます。カーネルの実行を抽象化することでデータと処理が統合され、SYCL 上に実装できる並列プロ
グラミング・モデルの抽象化と柔軟性が向上します。

第 4 章 SYCL プログラミング・インターフェイス | 247

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
コマンドグループ関数オブジェクトと handler クラスは、コマンド・グループ・スコープをカプセル化するインターフェイスとして機能します。SYCL カーネル関数は関数オブジェクトとして定義されます。すべてのデバイスデータへのアクセスはこのグループ内で定義され、すべての転送は SYCL ランタイムによって管理されます。デバイスとホストのデータアクセスに関するデータ転送の規則については 4.7
節で詳しく説明しています。ここでは、バッファー (4.7.2 節) およびアクセサー (4.7.6 節) クラスについて説明します。SYCL アプリケー
ションのメモリーモデルの概要については、3.8.1 節で説明します。
キューへのコマンドグループ関数オブジェクトのエンキューに失敗したり、正しく実行されないことがあります。ユーザーは、コマンド
グループをプライマリー・キューに送信する際にセカンダリー・キューも指定できます。SYCL ランタイムがプライマリー・キューへのコ
マンドグループのエンキューまたは実行に失敗すると、SYCL ランタイムはセカンダリー・キューでコマンドグループの実行を試みることができます。SYCL ランタイムがプライマリー・キューからセカンダリー・キューへフォールバックする可能性や、フォールバックできな
い状況は仕様では定義されていません。コマンドグループがセカンダリー・キューで実行されていても、フォールバック・キューが実行に利用されているかにかかわりなく、コマンドグループ内のホストコードが一度だけ実行される要件は同じです。
コマンドグループ handler クラスは、コマンドグループのスコープ内で実行可能なすべてのメンバー関数のインターフェイスを提供し、すべてのデータアクセス要求のスコープ・オブジェクトとしても提供されます。コマンド・グループ・ハンドラーのクラスは、コマンド・グ
ループ・スコープ内のすべてのコマンドをキューに送信するインターフェイスを提供します。

4.9.4. コマンドグループ handler クラス
コマンド・グループ・ハンドラー・オブジェクトは、SYCL ランタイムでのみ構築できます。コマンド・グループ・スコープで定義されたすべてのアクセサーは、パラメーターとしてコマンド・グループ・ハンドラーのインスタンスを受け取り、すべてのカーネル呼び出し関数はこのクラスのメンバー関数となります。
SYCL handler クラスのコンストラクターを表 129 に示します。
SYCL handler クラスのインスタンスをムーブまたはコピーすることは許可されません。
1.

namespace sycl {2.
3.

class handler {4.

private:5.
6.

// 定義されたコンストラクターを実装

7.

handler(__unspecified__);8.
9.

public:10.
11.

template <typename DataT, int Dimensions, access_mode AccessMode,

12.

target AccessTarget, access::placeholder IsPlaceholder>

13.

void require(accessor<DataT, Dimensions, AccessMode, AccessTarget,

14.

IsPlaceholder> acc);

15.
16.

void depends_on(event depEvent);

17.
18.

void depends_on(const std::vector<event>& depEvents);

19.
20.

//----- バックエンドの相互インターフェイス

21.

//

22.

template <typename T>

23.

void set_arg(int argIndex, T&& arg);

24.

248 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
25.

template <typename...Ts>26.

void set_args(Ts&&... args);

27.
28.

//------ カーネル・ディスパッチ API

29.

//

30.

// 注: カーネル・ディスパッチ関数において、テンプレート・パラメーター

31.

// 「typename KernelName」 はオプションです

32.

//

33.

template <typename KernelName, typename KernelType>34.

void single_task(const KernelType& kernelFunc);

35.
36.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

37.

template <typename KernelName, int Dimensions, typename...Rest>

38.

void parallel_for(range<Dimensions> numWorkItems,

39.

Rest&&... rest);

40.
41.

// SYCL 2020 では非推奨

42.

template <typename KernelName, typename KernelType, int Dimensions>43.

void parallel_for(range<Dimensions> numWorkItems,

44.

id<Dimensions> workItemOffset,

45.

const KernelType& kernelFunc);

46.
47.

// パラメーター・パックは次のように機能します: Reductions&&... reductions, const KernelType& kernelFunc

48.

template <typename KernelName, int Dimensions, typename...Rest>

49.

void parallel_for(nd_range<Dimensions> executionRange,

50.

Rest&&... rest);

51.
52.

template <typename KernelName, typename WorkgroupFunctionType, int Dimensions>53.

void parallel_for_work_group(range<Dimensions> numWorkGroups,

54.

const WorkgroupFunctionType& kernelFunc);

55.
56.

template <typename KernelName, typename WorkgroupFunctionType, int Dimensions>57.

void parallel_for_work_group(range<Dimensions> numWorkGroups,

58.

range<Dimensions> workGroupSize,

59.

const WorkgroupFunctionType& kernelFunc);

60.
61.

void single_task(const kernel& kernelObject);

62.
63.

template <int Dimensions>64.

void parallel_for(range<Dimensions> numWorkItems, const kernel& kernelObject);

65.
66.

template <int Dimensions>67.

void parallel_for(nd_range<Dimensions> ndRange, const kernel& kernelObject);

68.
69.
70.

//------ USM 関数

71.

//

72.
73.

void memcpy(void* dest, const void* src, size_t numBytes);

74.
75.

template <typename T>

76.

void copy(const T* src, T* dest, size_t count);

第 4 章 SYCL プログラミング・インターフェイス | 249

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
77.
78.

void memset(void* ptr, int value, size_t numBytes);

79.
80.

template <typename T>

81.

void fill(void* ptr, const T& pattern, size_t count);

82.
83.

void prefetch(void* ptr, size_t numBytes);

84.
85.

void mem_advise(void* ptr, size_t numBytes, int advice);

86.
87.
88.

//------ 明示的メモリー操作 API

89.

//

90.

template <typename SrcT, int SrcDim, access_mode SrcMode, target SrcTgt,

91.

access::placeholder IsPlaceholder, typename DestT>

92.

void copy(accessor<SrcT, SrcDim, SrcMode, SrcTgt, IsPlaceholder> src,

93.

std::shared_ptr<DestT> dest);

94.
95.
96.
97.
98.
99.

template <typename SrcT,
typename DestT, int DestDim, access_mode DestMode, target DestTgt,
access::placeholder IsPlaceholder>
void copy(std::shared_ptr<SrcT> src,
accessor<DestT, DestDim, DestMode, DestTgt, IsPlaceholder> dest);

100.
101.

template <typename SrcT, int SrcDim, access_mode SrcMode, target SrcTgt,

102.

access::placeholder IsPlaceholder, typename DestT>

103.

void copy(accessor<SrcT, SrcDim, SrcMode, SrcTgt, IsPlaceholder> src,

104.

DestT* dest);

105.
106.

template <typename SrcT,

107.

typename DestT, int DestDim, access_mode DestMode, target DestTgt,

108.

access::placeholder IsPlaceholder>

109.
110.

void copy(const SrcT* src,
accessor<DestT, DestDim, DestMode, DestTgt, IsPlaceholder> dest);

111.
112.

template <typename SrcT, int SrcDim, access_mode SrcMode, target SrcTgt,

113.

access::placeholder SrcIsPlaceholder, typename DestT, int DestDim,

114.

access_mode DestMode, target DestTgt,

115.

access::placeholder DestIsPlaceholder>

116.
117.

void copy(accessor<SrcT, SrcDim, SrcMode, SrcTgt, SrcIsPlaceholder> src,
accessor<DestT, DestDim, DestMode, DestTgt, DestIsPlaceholder> dest);

118.
119.

template <typename T, int Dim, access_mode Mode, target Tgt, access::placeholder IsPlaceholder>120.

void update_host(accessor<T, Dim, Mode, Tgt, IsPlaceholder> acc);

121.
122.

template <typename T, int Dim, access_mode Mode, target Tgt, access::placeholder IsPlaceholder>

123.

void fill(accessor<T, Dim, Mode, Tgt, IsPlaceholder> dest, const T& src);

124.
125.

void use_kernel_bundle(const kernel_bundle<bundle_state::executable>& execBundle);

126.
127.

template<auto& SpecName>

128.

void set_specialization_constant(

250 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
129.

typename std::remove_reference_t<decltype(SpecName)>::value_type value);

130.
131.

template<auto& SpecName)

132.

typename std::remove_reference_t<decltype(SpecName)>::value_type

133.

get_specialization_constant();

134.
135.

};

136.

} // namespace sycl

表 129. handler クラスのコンストラクター
コンストラクター

説明handler(__unspecified__)

不特定の実装定義コンストラクター。

4.9.4.1. 要件を追加する SYCL 関数
コマンド・グループ・ハンドラーからアクセサーが作成されると、アクセサーのデータ要件がコマンドグループに暗黙的に追加されます。
ただし、プレースホルダー・アクセサーを作成する場合にはこれは行われません。プレースホルダー・アクセサーの要件を作成するには、コードから handler::require() メンバー関数を呼び出します。
SYCL イベントにより、コマンドグループの要件を作成することもできます。その場合、コマンドグループを実行する前に、イベントによって発生するアクションを完了する必要があることが求められます。この要件は、コードが handler::depends_on() メンバー関数を呼び出すときに追加されます。
表 130. handler クラスのメンバー関数
メンバー関数説明

template <typename DataT, int Dimensions,

アクセサーに関連付けられたメモリー・オブジェクトへのアクセス

access_mode AccessMode, target AccessTarget,が必要です。

access::placeholder IsPlaceholder>
void require(accessor<DataT, Dimensions, AccessMode,
AccessTarget, IsPlaceholder> acc)

コマンドグループには、カーネルを実行する前に、指定されたメ
モリー・オブジェクトにアクセスする必要があるという要件があります。アクセサーがすでにコマンドグループに登録されている場
合、この関数を呼び出しても効果はありません。
(acc.empty() == true) の場合、errc::invalid エラーコードで例外
をスローします。

void depends_on(event depEvent)

コマンドグループには、このコマンドグループのアクションを実行する前に、depEvent で示されるアクションを完了する必要があるという要件があります。

void depends_on(const std::vector<event>& depEvents)

コマンドグループには、このコマンドグループのアクションを実行する前に、depEvent の各イベントで示されるアクションを完了する必要があるという要件があります。

第 4 章 SYCL プログラミング・インターフェイス | 251

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

4.9.4.2. カーネルを呼び出す SYCL 関数
カーネルは、単一のタスク、基本データ並列カーネル、および work-group 内の nd-range、または階層的な並列処理として呼び出すことができます。
それぞれの関数は、オプションのカーネル名テンプレート・パラメーターを受け取ります。ユーザーはオプションでカーネル名を指定できますが、省略されるとカーネルの実装定義名が適用されます。
カーネルを起動するすべての関数は、コマンドグループ handler クラス (4.9.4 節) のメンバー関数であり、コマンド・グループ・スコー
プで提供されるすべてのメンバー関数をカプセル化する際に使用されます。表 131 にカーネル呼び出しに関連する handler クラスのメンバーを示します。
表 131. handler クラスのメンバー関数
メンバー関数説明

template <typename T>

この関数は、バックエンド固有の相互運用性機能を使用して構築

void set_arg(int argIndex, T&& arg)

されたカーネル、またはデバイスのビルトインカーネルの引数を設定する用途にのみ使用する必要があります。この関数を使用してほかのカーネルの引数を設定すると、動作は未定義となります。
この関数の詳細なセマンティクスは、それぞれの SYCL バックエンドの仕様で定義されます。

template <typename...Ts>
void set_args(Ts&&... args)

args のすべての引数が同じ順番で set_arg に渡され、インデック
スが 0 から増加するように特定のカーネルの引数を設定します。

template <typename KernelName, typename

SYCL カーネル関数をラムダ関数または名前付き関数オブジェク

KernelType>

ト・タイプとして定義して呼び出します。4.9.4.2 節で説明するよう

void single_task(const KernelType& kernelFunc)に、カーネル名 (typename KernelName) はオプションです。呼び出し可能な KernelType は、オプションで kernel_handler を
受 け 入 れ るこ と も で き ま す 。 そ の 場 合 SYCL ラ ン タイ ム は 、kernel_handler のインスタンスを構築して KernelType に渡します。

template <typename KernelName, int Dimensions,

SYCL カーネル関数をラムダ関数または名前付き関数オブジェク

typename...Rest>

ト・タイプとして定義して呼び出します。レンジが 1 次元である場

void parallel_for(

合、インデックス空間のインデックスを作成するため、項目またはrange<Dimensions> numWorkItems,

整数タイプ (int、size_t など) を指定します。ジェネリック関数は許Rest&&... rest)

可されますが、引数タイプは item になります。4.9.4.2 節で説明す
るように、カーネル名 (typename KernelName) はオプションです。rest パラメーター・パックは、reduction 関数によって作成される 0 個以上のオブジェクトと、それに続く呼び出し可能オブジェクトで構成されます。rest のオブジェクトごとに、カーネル関数
は、そのオブジェクトの reducer タイプに対応する追加の参照パ
ラメーターを同じ順番で受け取る必要があります。呼び出し可能
オブジェクトはオプションで kernel_handler を受け入れることもできます。その場合 SYCL ランタイムは、kernel_handler のインスタンスを構築して呼び出し可能オブジェクトに渡します。

252 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename KernelName, int Dimensions,

SYCL 2020 では非推奨です。SYCL カーネル関数をラムダ関数

typename...Rest>

または名前付き関数オブジェクト・タイプとして定義して呼び出し

void parallel_for(

ます。レンジが 1 次元である場合、インデックス空間のインデック

range<Dimensions> numWorkItems,

スを作成するため、項目または整数タイプ (int、size_t など) を指id<Dimensions> workItemOffset,

定します。ジェネリック関数は 許可されますが、引数タイプはconst KernelType& kernelFunc)

item に な り ま す 。 4.9.4.2 節 で 説 明 す る よ う に 、 カ ー ネ ル 名// SYCL 2020 では非推奨です。

(typename KernelName) はオプションです。rest パラメーター・
パックは、reduction 関数によって作成される 0 個以上のオブジェクトと、それに続く呼び出し可能オブジェクトで構成されます。rest のオブジェクトごとに、カーネル関数は、そのオブジェクトの reducer タイプに対応する追加の参照パラメーターを同じ順
番で受け取る必要があります。呼び出し可能オブジェクトはオプションで kernel_handler を受け入れることもできます。その場
合 SYCL ランタイムは、kernel_handler のインスタンスを構築して呼び出し可能オブジェクトに渡します。

template <typename KernelName, int Dimensions,

指定された nd-range で、ラムダ関数または名前付き関数オブ

typename...Rest>

ジェクト・タイプとして SYCL カーネル関数を定義して呼び出し、

void parallel_for(nd-range で定義されたインデックス空間でインデックスを作成

nd_range<Dimensions> executionRange,する nd-item を指定します。ジェネリック関数は許可されますが、Rest&&... rest)

引数タイプは nd-item になります。4.9.4.2 節で説明するように、
カーネル名 (typename KernelName) はオプションです。rest パ
ラメーター・パックは、reduction 関数によって作成される 0 個以
上のオブジェクトと、それに続く呼び出し可能オブジェクトで構成されます。rest のオブジェクトごとに、カーネル関数は、そのオブジェクトの reducer タイプに対応する追加の参照パラメーターを同じ順番で受け取る必要があります。呼び出し可能オブジェクト
はオプションで kernel_handler を受け入れることもできます。その場合 SYCL ランタイムは、kernel_handler のインスタンスを構築して呼び出し可能オブジェクトに渡します。
関連する executionRange で定義されたグローバルサイズが元のローカルサイズで均等に割り切れない非ゼロのインデックス空間を定義している場合、errc::nd_range エラーコード例外をス
ローします。

第 4 章 SYCL プログラミング・インターフェイス | 253

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename KernelName,

階層的なカーネルを起動する各 work-group のボディーをエンコー

typename WorkgroupFunctionType, int Dimensions>

ドするラムダ関数または名前付き関数オブジェクトを定義して呼び

void parallel_for_work_group(

出します。ジェネリック関数は許可されますが、引数タイプは group

range<Dimensions> numWorkGroups,になります。それぞれのconst WorkgroupFunctionType& kernelFunc)

parallel_for_work_item(..) メンバー関数への複数呼び出しが含ま

work-item の 実 行 を 表 すれることがあります。ランタイムで定義されたサイズの
num_work_groups work-group を起動します。詳細は 4.9.4.2 節で説明します。呼び出し可能な WorkgroupFunctionType は、オプションで kernel_handler を受け入れることもできます。その場合
SYCL ランタイムは、kernel_handler のインスタンスを構築してWorkgroupFunctionType に渡します。
template <typename KernelName,

階層的なカーネルを起動する各 work-group のボディーをエン

typename WorkgroupFunctionType, int Dimensions>

コードするラムダ関数または名前付き関数オブジェクトを定義しvoid parallel_for_work_group(て呼び出します。ジェネリック関数は許可されますが、引数タイ

range<Dimensions> numWorkGroups,

プは group になります。それぞれの work-item の実行を表す

range<Dimensions> workGroupSize,parallel_for_work_item メンバー関数への複数呼び出しが含const WorkgroupFunctionType& kernelFunc)

まれることがあります。それぞれの work_group_size workitem の num_work_groups work-group を起動します。詳細は4.9.4.2 節 で 説 明 し ま す 。 呼 び 出 し 可 能 なWorkgroupFunctionType は、オプションで kernel_handlerを受け入れることもできます。その場合 SYCL ランタイムは、
kernel_handlerの イ ン ス タ ン ス を 構 築 し てWorkgroupFunctionType に渡します。
void single_task(const kernel& kernelObject)

この関数は、バックエンド固有の相互運用性機能を使用して構築されたカーネルを呼び出す場合、またはデバイスのビルトイン
カーネルを呼び出す場合にのみ使用する必要があります。この関数を使用してほかのカーネルを呼び出すと、errc::invalid エラー
コードで非同期例外をスローします。この関数の詳細なセマン
ティクスは、それぞれの SYCL バックエンドの仕様で定義されますが、それはカーネルを一度だけ実行するようにします。
この起動関数は、handler::use_kernel_bundle() を介してコマンド・グループ・ハンドラーにバインドされた kernel_bundle を無視して、kernelObject を含むカーネルバンドルを暗黙的に使用します。kernelObject が、コマンドグループのプライマリー・
キューに関連付けられているデバイス、またはセカンダリー・
キューに関連付けられるデバイス (指定されていれば) のどちらとも互換性がない場合、errc::kernel_not_supported エラーコー
ドで例外をスローします。

254 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <int Dimensions> void parallel_for(

この関数は、バックエンド固有の相互運用性機能を使用して構築

range<Dimensions> numWorkItems,

されたカーネルを呼び出す場合、またはデバイスのビルトイン

const kernel& kernelObject)

カーネルを呼び出す場合にのみ使用する必要があります。この関数を使用してほかのカーネルを呼び出すと、errc::invalid エラー
コードで非同期例外をスローします。この関数の詳細なセマン
ティクスは、それぞれの SYCL バックエンドの仕様で定義されますが、それは指定されたレンジのインデックス値に対してカーネルを呼び出す必要がある場合です。
この起動関数は、handler::use_kernel_bundle() を介してコマンド・グループ・ハンドラーにバインドされた kernel_bundle を無視して、kernelObject を含むカーネルバンドルを暗黙的に使用します。kernelObject が、コマンドグループのプライマリー・
キューに関連付けられているデバイス、またはセカンダリー・
キューに関連付けられるデバイス (指定されていれば) のどちらとも互換性がない場合、errc::kernel_not_supported エラーコー
ドで例外をスローします。

template <int Dimensions> void parallel_for(

この関数は、バックエンド固有の相互運用性機能を使用して構築

nd_range<Dimensions> ndRange,

されたカーネルを呼び出す場合、またはデバイスのビルトイン

const kernel& kernelObject)

カーネルを呼び出す場合にのみ使用することです。この関数を使用してほかのカーネルを呼び出すと、errc::invalid エラーコード
で非同期例外をスローします。この関数の詳細なセマンティクス
は、それぞれの SYCL バックエンドの仕様で定義されますが、それは指定された ndRange に対してカーネルを呼び出すことです。
関連する executionRange で定義されたグローバルサイズが元のローカルサイズで均等に割り切れない非ゼロのインデックス空間を定義している場合、errc::nd_range エラーコード例外をス
ローします。
この起動関数は、handler::use_kernel_bundle() を介してコマンド・グループ・ハンドラーにバインドされた kernel_bundle を無視して、kernelObject を含むカーネルバンドルを暗黙的に使用します。kernelObject が、コマンドグループのプライマリー・
キューに関連付けられているデバイス、またはセカンダリー・
キューに関連付けられるデバイス (指定されていれば) のどちらとも互換性がない場合、errc::kernel_not_supported エラーコー
ドで例外をスローします。

4.9.4.2.1. single_task 呼び出しSYCL は、デバイスでシリアル実行されるカーネルをキューにエンキューする簡単なインターフェイスを提供します。カーネルの 1 つのインスタンスのみが実行されます。このインターフェイスは、SYCL デバイス上でシリアルタスクのチェーンを容易に作成し、それぞれがデータ転送を管理できるため、より複雑な並列アルゴリズムのプリミティブとして有用です。
この関数は、ランタイムによって作成された handler オブジェクトを使用してコマンドグループ内でのみ呼び出すことが可能です。カーネルで使用されるアクセサーは、同一コマンドグループ内で定義する必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 255

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
ローカルアクセサーは、単一タスクの呼び出しには指定できません。
1.

myQueue.submit([&](handler& cgh) {2.

cgh.single_task(3.

[=] () {4.

// [カーネルコード]

5.
6.

}));
});

単項インデックス空間にインデックス空間クラスが必要ないため、単一タスクではカーネルのメンバー関数のパラメーターを受け取りません。
kernel_handler はオプションですが、4.9.5.3 節で説明する single_task から呼び出される SYCL カーネル関数にパラメーターとして渡すことができます。
1.

myQueue.submit([&](handler& cgh) {2.

cgh.single_task(3.

[=] (kernel_handler kh) {4.

// [カーネルコード]

5.
6.

}));
});

4.9.4.2.2. parallel_for 呼び出しSYCL handler クラスの parallel_for メンバー関数は、コマンドグループで SYCL カーネル関数を定義および起動して、3 次元のイン
デックス空間で並列実行するインターフェイスを提供します。parallel_for メンバー関数には 3 つのオーバーロードがあり、それぞれが複雑性の異なるレベルで、異なる機能セットを持つインターフェイスのバリエーションを提供します。
最も単純なケースでは、ユーザーは SYCL range パラメーターを介してグローバルレンジ (インデックス空間内の work-item の総数)を提供するだけです。この場合、SYCL カーネル関数を表す関数オブジェクトは、次のいずれかを受け取る必要があります。
1.

単一の SYCL item パラメーター

2.

item パラメーターとして扱われる単一のジェネリック・パラメーター (template パラメーターまたは auto)

3.

SYCL item から暗黙的に変換されたほかのタイプで、range パラメーターで指定されるレンジ内で実行中の work-itemを表します。
ケース 3 では、item が暗黙的に id に変換されるため、カーネル関数はタイプ id の引数を受け入れることができます。また、1-D の item は暗黙的にタイプ変換されるため、1-D カーネル関数は整数タイプの引数 (int または size_t)を受け取ることもできます。さらに、カーネル関数が item から作成できるユーザー定義の引数タイプを受け取れるようにし、ユーザーが SYCL 上で独自の抽象化を利用できるようにします。

カーネル関数の実行は、SYCL カーネル関数のパラメーターが SYCL id または SYCL item のどちらでも同じです。それぞれのインターフェイスを介して SYCL カーネル関数を使用できる点が異なります。
以下は、ラムダ関数を使用する parallel_for の SYCL カーネル関数の呼び出しで SYCL id パラメーターを渡す例です。ここでは、グローバル id のみが利用できます。parallel_for のバリアントは、実行されるインデックス空間のグローバルレンジを照会する必要がな
い用途向けに設計されています。
1.
2.

myQueue.submit([&](handler& cgh) {accessor acc { myBuffer, cgh, write_only };

3.
4.
5.

cgh.parallel_for(range<1>(numWorkItems),[=] (id<1> index) {256 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
6.

acc[index] = 42.0f;

7.
8.

});
});

以下は、ラムダ関数を使用する parallel_for の SYCL カーネル関数の呼び出しで SYCL item パラメーターを渡す例です。ここでは、グローバル id とグローバルレンジの両方が照会できます。この parallel_for のバリアントは、実行されるインデックス空間のグローバル
レンジを照会する用途向けに設計されています。
1.

myQueue.submit([&](handler& cgh) {2.

accessor acc { myBuffer, cgh, write_only };3.
4.

cgh.parallel_for(range<1>(numWorkItems),5.

[=] (item<1> item) {6.

// カーネル引数タイプは item

7.

size_t index = item.get_linear_id();8.

acc[index] = index;

9.
10.

});
});

以下は、ラムダ関数を使用する parallel_for の SYCL カーネル関数の呼び出しで item として扱われる auto パラメーターを渡す例です。ここでは、グローバル id とグローバルレンジの両方が照会できます。テンプレート化された operator() を持つクラスを使用して同じ効果を実現できます。この parallel_for のバリアントは、グローバル id が変化するグローバルレンジを照会する用途向けに設計されています。
1.

myQueue.submit([&](handler& cgh) {2.

auto acc = myBuffer.get_access<access_mode::write>(cgh);3.
4.

cgh.parallel_for(range<1>(numWorkItems),5.

[=] (auto item) {6.

// カーネル引数タイプは item として自動的に扱われます7.

size_t index = item.get_linear_id();8.

acc[index] = index;

9.
10.

});
});

以下は、ラムダ関数を使用する parallel_for のSYCL カーネル関数の呼び出しで、整数型 (int、size_t など) パラメーターを渡す例です。
この例は、range<1> で parallel_for を呼び出す場合にのみ有効です。ここではグローバル id のみが利用できます。parallel_for のバ
リアントは、実行されるインデックス空間のグローバルレンジを照会する必要がない用途向けに設計されています。
1.

myQueue.submit([&](handler& cgh) {2.

auto acc = myBuffer.get_access<access_mode::write>(cgh);3.
4.

cgh.parallel_for(range<1>(numWorkItems),5.

[=] (size_t index) {6.

// カーネル引数タイプはsize_t

7.

acc[index] = index;

8.
9.

});
});

オフセットのない parallel_for オーバーロードは、数値または 1 - 3 個の要素を持つ braced-init-list のいずれかで呼び出し可能です。
次の呼び出しは同等です。

• parallel_for(N, some_kernel) は、parallel_for(range<1>(N), some_kernel) と同じ効果があります。

第 4 章 SYCL プログラミング・インターフェイス | 257

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現• parallel_for({N}, some_kernel) は、parallel_for(range<1>(N), some_kernel) と同じ効果があります。
• parallel_for({N1, N2}, some_kernel) は、parallel_for(range<2>(N1, N2), some_kernel) と同じ効果があります。
• parallel_for({N1, N2, N3}, some_kernel) は、parallel_for(range<3>(N1, N2, N3), some_kernel) と同じ効果があります。
以下は、明示的な range オブジェクトの代わりに数値を指定して parallel_for を呼び出す例です。
1.

myQueue.submit([&](handler& cgh) {2.

auto acc = myBuffer.get_access<access_mode::write>(cgh);

3.
4.

// parallel_for を呼び出す回数 (numWorkItems)

5.

cgh.parallel_for(numWorkItems,6.

[=] (auto item) {7.

size_t index = item.get_linear_id();8.

acc[index] = index;

9.
10.

});
});

上記の parallel_for メンバー関数のオーバーロードを介して呼び出された SYCL カーネル関数では、ローカルアクセサーや workgroup バリアは許可されません。
次の 2 つの例は、各次元に 3 つの要素がある 3D グリッドでカーネル関数オブジェクトを起動する方法を示しています。最初の例では
work-item ID の範囲は 0 から 2 であり、次の例の work-item ID の範囲は 1 から 3 です。
1.

myQueue.submit([&](handler& cgh) {2.

cgh.parallel_for(3.

range<3>(3,3,3), // グローバルレンジ

4.

[=] (item<3> it) {5.

//[カーネルコード]

6.
7.

});
});

8.
9.

// オフセット・パラメーターを指定するこの形式の parallel_for は SYCL 2020 では非推奨

10.

myQueue.submit([&](handler& cgh) {11.

cgh.parallel_for(12.

range<3>(3,3,3), // グローバルレンジ

13.

id<3>(1,1,1), // オフセット

14.

[=] (item<3> it) {15.

//[カーネルコード]

16.
17.

});
});

parallel_for 呼び出しの最後の例では、work-item と work-group の低レベルの機能を有効にします。これは、実行時に通信や同期を行う work-item のグループが必要となる場合に役立ちます。これらは、parallel_for (nd_range,...) と nd_item クラスを介して SYCL
で提供されます。この場合、開発者はカーネルのエンキューを細かく制御するため、カーネルが実行される nd_range を定義する必要があります。parallel_for のこのバリエーションは、ローカルおよびグローバルレンジの両方を指定し、グローバルな work-item 数と関連する work-group 数を定義する nd_range を想定します。SYCL カーネル関数を表す関数オブジェクトは、次のいずれかを受け取る必要があります。
1.

単一の SYCL nd_item パラメーター

2.

nd_item パラメーターとして扱われる単一のジェネリック・パラメーター (template パラメーターまたは auto)

258 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
3.

SYCL nd_item から暗黙的に変換されたほかのタイプで、nd_range パラメーターで指定されるレンジ内で実行中の
work-item を表します。

nd_item パラメーターは、work-item に関するすべての情報とレンジ内の位置を示し、work-group バリアを使用して work-group 内の work-item 間の同期を行う関数にアクセスできるようにします。

ケース 3 には、nd_item から作成できるユーザー定義タイプが含まれており、ユーザーは SYCL 上に独自の抽象化を利用できます。

次の例は、各次元が 8 つの work-group に分割された 4 つの 3 次元グリッドで 64 個の work-item を起動します。work-item の各グ
ループは、work-group バリアと同期します。
1.

myQueue.submit([&](handler& cgh) {2.

cgh.parallel_for(3.

nd_range<3>(range<3>(4, 4, 4), range<3>(2, 2, 2)), [=](nd_item<3> item) {4.

// [カーネルコード]5.

// 内部同期

6.

group_barrier(item.get_group());

7.

// [カーネルコード]

8.
9.

});
});

これらすべてのケースにおいて、ベースとなる nd-range が作成され、関数オブジェクトとして定義されるカーネルが作成され、コマンド・グループ・スコープの一部としてキューに投入されます。
parallel_for の一部の形式は、id<Dimensions> タイプのオフセット・パラメーターを受け入れます。ここで、id の次元数は反復空間を決定する range の次元数と同じです。そのような parallel_for は、オフセットのない形式と同じ回数の反復を実行します。
唯一の違いは、カーネル関数に渡される id や item パラメーターには、暗黙の追加 offset 値があることです。オフセット・パラメーター
は SYCL 2020 では非推奨です。
オフセットは、nd_range コンストラクターへの 3 番目のパラメーターを介して nd_range を受け入れる parallel_for を渡すこともできます。これらの parallel_for も、オフセットがない形式と同じ回数の反復を実行します。両者の違いは、カーネル関数に渡される
nd_item パラメーターには、構成要素グローバル id に暗黙的に追加されたオフセット値があることです。このオフセット・パラメー
ターは、SYCL 2020 では非推奨になりました。
kernel_handler は、オプションですが、parallel_for の両方のバリアントから呼び出される SYCL カーネル関数にパラメーターとして渡すことができます。
1.

myQueue.submit([&](handler& cgh) {2.

cgh.parallel_for(3.

range<3>(3,3,3), // グローバルレンジ

4.

[=] (item<3> it, kernel_handler kh) {5.

// [カーネルコード]

6.
7.

});
});

8.
9.

// オフセット・パラメーターを指定するこの形式の parallel_for は SYCL 2020 では非推奨

10.

myQueue.submit([&](handler& cgh) {

11.
12.

cgh.parallel_for(range<3>(3,3,3), // グローバルレンジ

第 4 章 SYCL プログラミング・インターフェイス | 259

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
13.

id<3>(1,1,1), // オフセット

14.

[=] (item<3> it, kernel_handler kh) {15.

// [カーネルコード]

16.
17.

});
});

4.9.4.2.3. 階層的な呼び出しの並列処理
階層的並列カーネル実行インターフェイスは、nd-range インターフェイスで利用できる機能を提供しますが、公開方法が異なります。
前述の例の 16 個の work-group で同じ 64 個の work-item を実行するには、外部の parallel_for_work_group を呼び出してグ
ループを作成します。メンバー関数 handler::parallel_for_work_group は、各グループのサイズがランタイムによって選択される
ように、work-group 数によって、または詳細な制御を必要とするユーザーの work-group 数と work-item 数によってパラメーター
化されます。
外部 parallel_for_work_group 呼び出しの本体は、ラムダ関数または関数オブジェクトで構成されます。この関数オブジェクトの本体には、work-group 全体で一度だけ実行されるコードが含まれます。コードに副作用がなく、コンパイラーのヒューリスティックが効率的であると示している場合、このコードは各 work-item に対して実行されます。
この領域内で宣言された変数は、ローカルメモリーのセマンティクスを持ち、work-group 内のすべての work-item で共有されます。
デバイス・コンパイラーが、変数の配列が work-group の存続期間中に単一の work-item によってのみアクセスされることが判断できる場合 (アクセスが変換なしに work-item の id から派生するなど)、プライベート・メモリーまたはレジスターにデータを割り当てできます。
work-item ごとに使用するプライベート・メモリーを保証するため、private_memory クラスでデータをラップできます。このクラスは、
グループ全体の特定のグループでプライベート・データを作成するだけです。現在の work-item の id は、正しいデータを取得するため
すべてのアクセスに渡されます。
private_memory クラスには次のインターフェイスがあります。
リスト 1. プライベート・メモリー・クラス
1.

namespace sycl {2.

template <typename T, int Dimensions = 1>

3.

class private_memory {4.

public:5.

// work-item の数をベースに直接構築

6.

private_memory(const group<Dimensions>&);7.
8.

// 現在の work-item のインスタンスにアクセス

9.

T& operator()(const h_item<Dimensions>& id);

10.

};

11.

}

表 132. private_memory クラスのコンストラクター
コンストラクター説明

private_memory(const group<Dimensions>&)

タイプ T のオブジェクトを、各 work-item のベースとなるプライ
ベート・メモリーに配置します。タイプ T はデフォルト・コンストラ
クターである必要があります。ベースとなるコンストラクターは、
work-item ごとに呼び出されます。

260 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
表 133. private_memory クラスのメンバー関数
メンバー関数説明

T& operator ()(const h_item<Dimensions>& id)

work-item のオブジェクトへの参照を取得します。

プライベート・メモリーは、parallel_for_work_item ループの反復ごとではなく、ベースとなる work-item ごとに割り当てられます。プ
ライベート・メモリー・オブジェクトのインスタンス数は、work-group サイズが parallel_for_work_group 呼び出しに渡された場合にのみ直接制御されます。ベースとなる work-group サイズがランタイムによって選択されている場合、プライベート・メモリーのインスタ
ンス数はプログラムからは不透過です。従って、明示的なプライベート・メモリー宣言は注意して使用し、parallel_for_work_item ルー
プのいずれのインスタンスが同じ変数を共有するか完全に理解する必要があります。
また、ラムダ関数内には parallel_for_work_item への呼び出しシーケンスを含めることができます。これらの内部並列実行の最後で
work-group が同期します。その結果、次のコードの parallel_for_work_item 呼び出しのペアは、前述の work-group バリアを使用した並列実行を同等です。
1.

myQueue.submit([&](handler& cgh) {2.

// それぞれ 8 つのワーク項目からなる 8 つのワークグループを発行

3.

cgh.parallel_for_work_group(4.

range<3>(2, 2, 2), range<3>(2, 2, 2), [=](group<3> myGroup) {5.
6.

// [workgroup のコード]

7.

int myLocal; // この変数は workitem 間で共有されます8.

// この変数は work-item ごとに個別にインスタンス化されます9.

private_memory<int> myPrivate(myGroup);

10.
11.

// 並列 work-item を発行。work-group ごとに発行される数は、parallel_for_work_group の12.

// work-group のサイズによって決定されます このケースでは、

13.

// 8 つの work-item それぞれに対し parallel_for_work_item のボディーを実行し、

14.

// 8 つの work-group が結果としてグローバル/合計で 64 回が実行されます。

15.

myGroup.parallel_for_work_item([&](h_item<3> myItem) {16.

//[work-item のコード]

17.

myPrivate(myItem) = 0;

18.

});

19.
20.

// 暗黙のワークグループのバリア

21.
22.

// ループ間でプライベート変数を伝搬

23.

myGroup.parallel_for_work_item([&](h_item<3> myItem) {24.

//[work-item のコード]

25.

output[myItem.get_global_id()] = myPrivate(myItem);

26.

});

27.

//[workgroup のコード]

28.
29.

});
});

work-item ル ー プ の よ り 柔 軟 性 の あ る 次 元 を 使 用 す る こ と は 有 効 で す 。 次 の 例 で は 、 8 つ の ワ ー ク グ ル ー プ を 発 行 し 、
parallel_for_work_group 呼び出しに work-group サイズを渡さず、ランタイムでサイズを決定します。parallel_for_work_item
ループのサイズも異なることがありますが、その実行レンジは work-group の次元とは関係なく、コンパイラーがギャップを埋めるため
適切な反復空間を生成します。この場合、h_item はカーネルと parallel_for_work_item の呼び出しレンジの両方を反映するローカ
ル id とレンジへのアクセスを可能にします。

第 4 章 SYCL プログラミング・インターフェイス | 261

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
1.

myQueue.submit([&](handler& cgh) {2.

// 8 つの work-group を発行 work-group サイズが指定されていないため、ランタイムで選択されます3.

cgh.parallel_for_work_group(4.

range<3>(2, 2, 2), [=](group<3> myGroup) {5.
6.

//それぞれの work-group の work-item のセットを起動します。work-group のサイズが7.

// parallel_for_work_group で指定されておらず、論理レンジが parallel_for_work_item に

8.

// 指定されていないため、work-item 数はランタイムによって選択されます。

9.

myGroup.parallel_for_work_item([=](h_item<3> myItem) {10.

//[work-item のコード]

11.

});

12.
13.

// 暗黙のワークグループのバリア

14.
15.

// ランタイムによって選択されたベースとなる work-group サイズによって実行される

16.

// 512 の論理 work-item を起動します。myItem を使用して、論理的および物理的な17.

// work-item ID を照会できます。512 個の論値 work-item が work-group ごとに実行されるため、

18.

// parallel_for 本体は 8 * 512 = 4096 回グローバル/合計で実行されます。

19.

myGroup.parallel_for_work_item(range<3>(8, 8, 8), [=](h_item<3> myItem) {20.

//[work-item のコード]

21.

});

22.

//[workgroup のコード]

23.
24.

});
});

このインターフェイスは、並列プログラミングのパラダイムを克服するためより直感的な方法を提供します。要約すると、階層的モデル
によって、開発者は parallel_for_work_group と入れ子になった parallel_for_work_item 関数を使用して、work-group レベルとwork-item レベルで実行を区別できます。また、ホストでの実行がより効率良くなるよう複雑なループ・フィッションを必要とせず、コンパイラーに可視性をもたらします。
kernel_handler はオプションですが、parallel_for_work_group の任意のバリアントから呼び出される SYCL カーネル関数にパラメーターとして渡すことができます。
1.

myQueue.submit([&](handler& cgh) {2.

// それぞれ 8 つのワーク項目からなる 8 つのワークグループを発行

3.

cgh.parallel_for_work_group(4.

range<3>(2, 2, 2), range<3>(2, 2, 2), [=](group<3> myGroup,5.

kernel_handler kh) {6.
7.

// [workgroup のコード]

8.

int myLocal; // この変数は workitem 間で共有されます9.

// この変数は work-item ごとに個別にインスタンス化されます10.

private_memory<int> myPrivate(myGroup);

11.
12.

// 並列 work-item を発行。work-group ごとに発行される数は、parallel_for_work_group の13.

// work-group のサイズによって決定されます このケースでは、

14.

// 8 つの work-item それぞれに対し parallel_for_work_item のボディーを実行し、

15.

// 8 つの work-group が結果としてグローバル/合計で 64 回が実行されます。

16.

myGroup.parallel_for_work_item([&](h_item<3> myItem) {17.

//[work-item のコード]

18.

myPrivate(myItem) = 0;

19.

});

262 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
20.
21.

// 暗黙のワークグループのバリア

22.
23.

// ループ間でプライベート変数を伝搬

24.

myGroup.parallel_for_work_item([&](h_item<3> myItem) {25.

//[work-item のコード]

26.

output[myItem.get_global_id()] = myPrivate(myItem);

27.

});

28.

//[workgroup のコード]

29.
30.

});
});

4.9.4.3. 明示的なメモリー操作を行う SYCL 関数
カーネルに加えて、コマンド・グループ・オブジェクトはコマンド・グループ・ハンドラーのコピー API を使用して、ホストおよびデバイスのメモリーを手動で操作するために利用できます。手動でのコピー操作は、デバイス上で実行される特殊カーネルと見なすことができます。通常この操作は、バックエンドの一部であるホスト API を使用して実装されます (OpenCL エンキューコピー操作など)。
これらの明示的なコピー操作にはソースとデスティネーションがあります。アクセサーが操作のソースである場合、デスティネーション
はホストポインターまたは別のアクセサーにできます。source アクセサーは access_mode::read または access_mode::read_write
アクセスモードのいずれかである必要があります。
アクセサーが明示的なコピー操作のデスティネーションの場合、ソースはホストポインターまたは別のアクセサーである可能性がありま す 。 デ ス テ ィ ネ ー シ ョ ン ・ ア ク セ サ ー は 、 access_mode::write 、 access_mode::read_write 、 access_mode::discard_write 、
access_mode::discard_read_write アクセスモードのいずれです。
ア ク セ サ ー が こ れ ら の 明 示 的 な コ ピ ー 操 作 の パ ラ メ ー タ ー と し て 使 用 さ れ る 場 合 、 タ ー ゲ ッ ト は target::device ま た は
target::constant_buffer のいずれかである必要があります。
アクセサーがソースとデスティネーションの両方である場合、操作は SYCL ランタイムによって制御されるオブジェクトで実行されます。
SYCL アプリケーションのメモリーモデルに従ってデータの更新に別のパスが利用可能である場合、SYCL ランタイムは明示的なコ
ピー内操作を実行できません。
メモリー・オブジェクトの最新のコピーは、SYCL ランタイムによって制御される任意のコンテキスト、または SYCL ランタイムによって制御されるホストポインターに存在する可能性があります。SYCL ランタイムは、コマンドグループが実行を完了すると、データがデス
ティネーションに確実にコピーされるようにします。
ホストポインターが、これらの明示的なメモリー操作のホストまたはデスティネーションとして使用される場合、そのポインターがアクセサーによってアクセス許可されるのと同じ量のメモリーを割り当てるのはユーザーの責任です。
int タイプの 10 要素のレンジにアクセスする場合、ホストポインターには少なくとも 10 * sizeof(int) バイトのメモリーが割り当てられている必要があります。
update_host メンバー関数は特殊なケースです。このメンバー関数はアクセサーのみを必要とし、ホスト上のデータの内部コピーがある場合は、それを更新するようにランタイムに指示します。これは、ユーザーが手動でホストポインターの同期を行う際に便利です。例
えば、buffer コンストラクターのミューテックス・オブジェクトを介する場合などがあります。
表 134 に明示的なコピー操作のインターフェイスを示します。

第 4 章 SYCL プログラミング・インターフェイス | 263

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
表 134. handler クラスのメンバー関数
メンバー関数説明

template <typename SrcT, int SrcDim,

src がアクセスするメモリー・オブジェクトの内容を、dest が指す

access_mode SrcMode,

メモリーにコピーします。dest はホストポインターで、少なくともtarget SrcTgt, typename DestT,

src がアクセスするレンジ以上のバイト数でなければなりません。

access::placeholder IsPlaceholder>
void copy(accessor<SrcT, SrcDim,
SrcMode, SrcTgt,
IsPlaceholder> src,
std::shared_ptr<DestT> dest)
template <typename SrcT, typename DestT, int DestDim,

src が指すメモリーの内容を、dest がアクセスするメモリー・オブaccess_mode DestMode,

ジェクトにコピーします。src はホストポインターで、少なくともtarget tgDestT,

dest がアクセスするレンジ以上のバイト数がなければなりませaccess::placeholder IsPlaceholder>ん。

void copy(std::shared_ptr<SrcT> src,
accessor<DestT, DestDim,
DestMode, tgDestT,
IsPlaceholder> dest)
template <typename SrcT, int SrcDim,

src がアクセスするメモリー・オブジェクトの内容を、dest が指す

access_mode SrcMode,

メモリーにコピーします。dest はホストポインターで、少なくともtarget SrcTgt, typename DestT,

src がアクセスするレンジと同じバイト数がなければなりません。

access::placeholder IsPlaceholder>
void copy(accessor<SrcT, SrcDim,
SrcMode, SrcTgt,
IsPlaceholder> src,
DestT* dest)
template <typename SrcT, typename DestT, int DestDim,

src が指すメモリーの内容を、dest がアクセスするメモリー・オブaccess_mode DestMode,

ジェクトにコピーします。src はホストポインターで、少なくともtarget tgDestT,

dest がアクセスするレンジ以上のバイト数がなければなりませaccess::placeholder IsPlaceholder>ん。

void copy(const SrcT* src,
accessor<DestT, DestDim,
DestMode, tgDestT,
IsPlaceholder> dest)

264 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename SrcT, int SrcDim,

src がアクセスするメモリー・オブジェクトの内容を、dest がアク

access_mode SrcMode, target SrcTgt,

セスするメモリー・オブジェクトにコピーします。src アクセサーの

access::placeholder IsSrcPlaceholder,

サイズによって、コピーされるバイト数が決定されます。dest には

typename DestT, int DestDim,

少なくともこのバイト数が必要です。dest のバイト数が少なすぎ

access_mode DestMode, target DestTgt,

ると、実装は errc::invalid エラーコードで同期例外をスローしま

access::placeholder IsDestPlaceholder>

す。

void copy(accessor<SrcT, SrcDim,
SrcMode, SrcTgt,
IsSrcPlaceholder> src,
accessor<DestT, DestDim,
DestMode, DestTgt,
IsDestPlaceholder> dest)
template <typename T, int Dim,

ホスト上の acc でアクセスされるメモリー・オブジェクトの内容

access_mode Mode, target Tgt,

は、このコマンド・グループ・オブジェクトの実行が完了すると最access::placeholder IsPlaceholder>

新であることが保証されます。

void update_host(accessor<T, Dim,mode, Tgt,
IsPlaceholder> acc)
template <typename T, int Dim,

src の値を dest がアクセスするメモリー・オブジェクトに複製しま

access_mode Mode, target Tgt,

す。T はスカラー値または SYCL ベクトルタイプでなければなりま

access::placeholder IsPlaceholder>

せん。

void fill(accessor<T, Dim, Mode, Tgt, IsPlaceholder> dest,
const T& src)
void memcpy(void* dest, const void* src, size_t numBytes)

numBytes のデータをポインター src からポインター dest にコ
ピーします。dest と src パラメーターは、それぞれホストポイン
ターまたはハンドラーのデバイス上でアクセス可能な USM 割り
当て内のポインターのいずれかである必要があります。USM 割り
当てへのポインターである場合、その場所はハンドラーのキューと同一コンテキストから作成されていなければなりません。USMの詳細については、4.8 節を参照してください。

template <typename T>

タイプ T の count 要素をポインター src からポインター dest にvoid copy(const T* src, T* dest, size_t count)

コピーします。dest と src パラメーターは、それぞれホストポイン
ターまたはハンドラーのデバイス上でアクセス可能な USM 割り
当て内のポインターのいずれかである必要があります。USM 割り
当てへのポインターである場合、その場所はハンドラーのキューと同一コンテキストから作成されていなければなりません。USMの詳細については、4.8 節を参照してください。

void memset(void* ptr, int value, size_t numBytes)

アドレス ptr から始まる numBytes バイトのメモリーを value で埋めます。ptr は、ハンドラーのキューと同じコンテキストの USM
割り当て内を指す必要があり、ポインターはキューのデバイスからアクセス可能でなければなりません。value は unsigned charとして解釈されることに注意してください。USM の詳細について
は、4.8 節を参照してください。

第 4 章 SYCL プログラミング・インターフェイス | 265

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

メンバー関数説明

template <typename T>

提供された pattern をターゲット USM ポインター ptr に複製しvoid fill(void* ptr, const T& pattern, size_t count)ます。ptr は、ハンドラーのキューと同じコンテキストの USM 割り
当て内を指す必要があり、ポインターはキューのデバイスからア
クセス可能でなければなりません。pattern は count 回数分埋められます。USM の詳細については、4.8 節を参照してください。

void prefetch(void* ptr, size_t numBytes)

アドレス ptr から始まる numBytes バイトのデータのプリフェッ
チをエンキューします。ptr は、ハンドラーのキューと同じコンテ
キストの USM 割り当て内を指す必要があり、ポインターはキューのデバイスからアクセス可能でなければなりません。USM の詳細については、4.8 節を参照してください。

void mem_advise(void* ptr, size_t numBytes, int advice)

ptr から始まる numBytes バイトの USM 領域に関連する情報を実装に提供するコマンドをエンキューします。ptr は、ハンドラーのキューと同じコンテキストの USM 割り当て内を指す必要があり、ポインターはキューのデバイスからアクセス可能でなければなりません。ptr の advice をデフォルト動作に戻す値 0 を除いて、
advice の値はベンダーまたはバックエンド固有です。USM の詳
細については、4.8 節を参照してください。

次のリストは、SYCL で明示的なコピー操作を行う方法を示します。この例では、std::vector の半分をデバイスにコピーし、デバイス上のバッファーの残りの内容を変更することはありません。
1.

const size_t nElems = 10u;2.
3.

// ベクトルを作成して、0, 1, 2, 3, 4, 5, 6, 7, 8, 9 の値を設定

4.

std::vector<int> v { nElems };5.

std::iota(std::begin(v), std::end(v), 0);

6.
7.

// ユーザーのストレージに関連付けられていないバッファーを作成

8.

sycl::buffer<int, 1> b { range<1>(nElems) };9.
10.

// キューを作成

11.

queue myQueue;

12.
13.

myQueue.submit([&](handler& cgh) {14.

// バッファーの前半にアクセスできるグローバルバッファーへのレンジ付き書き込み15.

// アクセサーを取得します

16.

accessor acc { b, cgh, range<1>(nElems / 2), id<1>(0), write_only };17.

// ベクトルの最初の 5 つの要素をアクセサーに関連付けられた

18.

// バッファーにコピーします19.

cgh.copy(v.data(), acc);

20.

});

266 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

4.9.4.4. カーネルバンドルを使用する関数
1.

void use_kernel_bundle(const kernel_bundle<bundle_state::executable>& execBundle);

効果: handler に関連付けられたコマンドグループは、カーネル起動コマンドのいずれかで kernel_bundle execBundle のデバイスイメージを使用します。kernel_bundle が複数のデバイスを含む場合、カーネルが送信されるデバイスと互換性のあるイメージでは、選択されるデバイスイメージは実装によって定義されます。
コマンドグループが execBundle と互換性のあるデバイスイメージに含まれないカーネルを呼び出そうとすると、カーネル起動コマン
ドは errc::kernel_not_supported エラーコードで同期例外をスローします。コマンドグループにセカンダリー・キューがある場合、execBundle にはプライマリー・キューのデバイスとセカンダリー・キューのデバイスの両方と互換性のあるカーネルが含まれる必要があります。含まれていないと、カーネル起動コマンドはこの例外をスローします。
特殊化定数を設定するハンドラーメソッドはカーネル・バンドル・メソッドと互換性がないため、同じ コマンドグループですでにhandler::set_specialization_constant() が呼び出されている場合、アプリケーションはこの関数を呼び出してはなりません。
スロー:• 関連付けられたプライマリー・キューを介してコマンド・グループ・ハンドラーに関連付けられたコンテキスト、またはセカンダ
リー・キューが、execBundle で指定されたカーネルバンドルのコンテキストと異なる場合、errc::invalid エラーコードで例外がス
ローされます。

• handler::set_specialization_constant() がこのコマンドグループから呼び出されると、errc::invalid エラーコードで例外がス
ローされます。

4.9.5. 特殊化定数
デバイスコードは、SYCL アプリケーションの実行中に値を動的に変更できる特殊化定数を利用できます。これらの定数値は、SYCLカーネル関数が呼び出されると固定され、カーネルの実行中は変更されません。ただし、アプリケーションは、カーネルを呼び出すたびに特殊化定数に新しい値を設定できるため、呼び出しごとに異なる値に調整できます。
アプリケーションが特殊化定数を使用するには 2 つの方法があります。1 つは kernel_bundle オブジェクトを作成する必要がありますが、もう一方は必要ありません。両者の構文はほとんど同じです。どちらも同じ方法で特殊化定数を宣言し、カーネルは同じ方法でその値を受け取ります。主な違いは、その値が handler::set_specialization_constant() を介して設定されるか、
kernel_bundle::set_specialization_constant() を介して設定されるかです。これは 2 つの方法は、どちらももう一方と互換性がないため、同じコマンドグループで混在して使用することはできません。

カーネルバンドルのオンラインコンパイルをサポートする実装では、カーネルバンドルを使用する特殊化定数の両方の方法を実装する必要があります。そのため、アプリケーションは特殊化定数に新しい値を設定してカーネルを呼び出すたびに、オーバーヘッドが生じることを考慮する必要があります。一般的な実装では、
handler::set_specialization_constant() を介して設定された特殊化定数値を記録し、カーネルが呼び出されるまで (例えば parallel_for() を介して) その値を保持します。この時点で、実装は呼び出されたカーネルを含むバンドルを決定します。そのバンドルが、ハンドラーのデバイス向けにコンパイルされ、特殊化定数の正しい 値でコ ンパイ ルされて いる場合、 カー ネル の呼び出しがスケジュー ルさ れます。それ以 外では、実装は呼び出し用にカーネルをスケジュールする前にバンドルをコンパイルします。そのため、特殊化
定数の値を頻繁に変更するアプリケーションでは、カーネルのバンドルを再コンパイルするオーバーヘッドが発生する可能性があります。

第 4 章 SYCL プログラミング・インターフェイス | 267

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現

4.9.5.1. 特殊化定数の宣言
特殊化定数は、specialization_id クラスで宣言する必要があり、次の制限があります。

• テンプレート・パラメーター T は、デバイスのコピー可能なタイプである必要があります。
• specialization_id 変数は、constexpr として宣言する必要があります。
• specialization_id 変数は、名前空間スコープまたはクラススコープのいずれかで宣言する必要があります。
• specialization_id 変数がクラススコープで宣言されている場合、名前空間スコープからの参照時にパブリックアクセス可能である必要があります。

• specialization_id 変数は、同じ名前でインライン名前空間で宣言されている別の識別子 X によってシャドー化されないため、Xの宣言後に specialization_id 変数にアクセスできなくなります。

• specialization_id 変数が名前空間で宣言されている場合、その名前空間 N は、N と同じ名前でインライン宣言された別の識別
子 X でシャドー化されるため、名前空間は X の宣言後 N にアクセスできなくなります。

一部の実装では、翻訳ユニットの終わりにその翻訳ユニットで宣言されている各 specialization_id 変数を参照するコードを概念的に挿入することが期待されます。上記の制限は、変数が翻訳ユニットの最後でアクセスできることを保証することで、これを可能にします。
この制限の例を以下に示します。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl;// (optional) avoids need for "sycl::" before SYCL names

3.
4.

struct Compound {int i; float f;};

5.
6.

constexpr specialization_id <int> a{1};7.

constexpr specialization_id <Compound> b{2, 3.14};

// OK

8.

inline constexpr specialization_id <int> c{3};

// OK

9.

static constexpr specialization_id <int> d{4};

// OK

10.

specialization_id <int> e{5};// ILLEGAL: not constexpr

// OK

11.
12.

struct Bar {13.

static constexpr specialization_id <int> f{6}; // OK

14.

};

15.

struct Baz {16.

struct Inner {17.

static constexpr specialization_id <int> g{7}; // OK

18.

};

19.

};

20.

class Boo {

21.
22.

static constexpr specialization_id <int> h{8}; // ILLEGAL: not public member
};

23.
24.

void Func() {25.

static constexpr specialization_id <int> i{9}; // ILLEGAL: not at namespace or

26.

// class scope

27.
28.

/* ... */}29.

268 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
30.

constexpr specialization_id <int> same_name{10}; // OK

31.

namespace foo {32.

constexpr specialization_id <int> same_name{11}; // OK

33.

}

34.

namespace {35.

constexpr specialization_id <int> same_name{12}; // OK

36.

}

37.

inline namespace other {38.

int same_name;39.

// variable with same name in enclosing

40.

// namespace scope

41.

}

42.

inline namespace other2 {43.

namespace foo {44.

// ILLEGAL: namespace name shadows "::foo"// namespace which contains

45.

// "specialization_id" variable.

46.
47.

// ILLEGAL: shadows "specialization_id"} // namespace foo} // namespace

クラスの概要を以下に示します。
1.

namespace sycl {2.
3.

template <typename T>

4.

class specialization_id{

5.

public:6.

using value_type = T;7.

template<class...Args >8.

explicit constexpr specialization_id(Args&&... args);

9.
10.

specialization_id(const specialization_id& rhs) = delete;11.

specialization_id(specialization_id&& rhs) = delete;

12.

specialization_id& operator=(const specialization_id& rhs) = delete;

13.
14.

specialization_id& operator=(specialization_id&& rhs) = delete;
};

15.
16.

} // namespace sycl

4.9.5.1.1. コンストラクター
template<class...Args>
explicit constexpr specialization_id(Args&&... args);
条件: std::is_constructible_v<T, Args...> が true と評価された場合にのみ利用できます。
効果: args... で初期化された T のインスタンスを含む specialization_id を構築します。これは、特殊化定数のデフォルト値を表します。

4.9.5.1.2. 特殊メンバー関数
specialization_id(const specialization_id& rhs) = delete;specialization_id(specialization_id&& rhs) = delete;// (1)// (2)

specialization_id&operator=(const specialization_id& rhs) = delete; // (3)specialization_id&operator=( specialization_id&& rhs) = delete;// (4)

第 4 章 SYCL プログラミング・インターフェイス | 269

SYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
1.

コピー・コンストラクターを削除。

2.

ムーブ・コンストラクターを削除。

3.

コピー代入オペレーターを削除。

4.

ムーブ代入オペレーターを削除。

4.9.5.2. 特殊化定数値の設定と取得
アプリケーションが kernel_bundle オブジェクトを作成することなく特殊化定数を使用する場合、handler クラスのメンバー関数を呼び出すことでコマンド・グループ・スコープの値を設定および取得できます。これらのメンバー関数には、テンプレート・パラメーター
SpecName があり、値は特殊化定数のタイプとデフォルト値を定義する specialization_id タイプ変数への参照でなければなりません。
カーネルバンドルを使用しない場合、コマンドグループから呼び出されたカーネルが使用する特殊化定数の値は、同じコマンドグルー
プで値を設定する呼び出しの影響を受けますが、呼び出しが同じコマンドグループ関数オブジェクトの別の呼び出しであっても、ほかのコマンドグループからの呼び出しの影響はありません。
template<auto& SpecName>
void set_specialization_constant(
typename std::remove_reference_t<decltype(SpecName)>::value_type value);
効果: このハンドラーのコマンドグループのアドレスが SpecName である特殊化定数の値を設定します。特殊化定数の値がそれ以前に同じコマンドグループで設定されている場合、値は上書きされます。
特殊化定数 SpecName がこのハンドラーのコマンドグループで呼び出されるカーネルで使用されていない場合でも、この関数が呼び出される可能性があります。その場合、呼び出されたカーネルには影響しません。
スロー:• カーネルバンドルが use_kernel_bundle() によって handler にバインドされている場合、errc::invalid エラーコードで例外をス
ローします。
template<auto& SpecName>
typename std::remove_reference_t<decltype(SpecName)>::value_type get_specialization_constant();
戻り値: このハンドラーのコマンドグループのアドレスが SpecName である特殊化定数の値を返します。このハンドラーのコマンドグ
ループでそれ以前に値が設定されている場合、その値が返されます。それ以外は、特殊化定数のデフォルト値が返されます。
スロー:• カーネルバンドルが use_kernel_bundle() によって handler にバインドされている場合、errc::invalid エラーコードで例外をス
ローします。

4.9.5.3. デバイスコードから特殊化定数値を読み取る
デバイスコードから特殊化定数値を読み取るには、SYCL カーネル関数を宣言して kernel_handler タイプのオブジェクトを最後のパラメーターとして受け取る必要があります。SYCL ランタイムは、特殊化定数の値を読み取るメンバー関数を持つオブジェクトを作成します。このクラスの概要を以下に示します。
1.

namespace sycl {

2.
3.
4.
5.

class kernel_handler {public:template<auto& SpecName>

270 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.9 カーネルを介して並列処理を表現
6.
7.

typename std::remove_reference_t<decltype(SpecName )>::value_type get_specialization_constant();
};

8.
9.

} // namespace sycl

4.9.5.3.1. メンバー関数
1.

template<auto& SpecName>

2.

typename std::remove_reference_t<decltype(SpecName)>::value_type3.

get_specialization_constant();

戻り値: アドレスが SpecName である特殊化定数の値を返します。カーネルバンドルにバインドされていないコマンドグループから呼び出されたカーネルでは、値はカーネルを呼び出す直前に handler::get_specialization_constant() が呼び出されたときに返される値と同一です。
カーネルバンド ルにバインド されている コマンドグループ から呼び出されたカーネルで は、値はバインドされたバンドルで
kernel_bundle::get_specialization_constant() が呼び出されたときに返される値と同一です。

4.9.5.4. 使用例
次の例は、畳み込みを実行して、特殊化定数を使用し係数値を設定します。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

3.
4.

using coeff_t = std::array<std::array<float, 3>, 3>;5.
6.

// 係数を読み取ります7.

coeff_t get_coefficients();

8.
9.

// 特殊化定数を特定

10.

constexpr specialization_id<coeff_t> coeff_id;

11.
12.
13.

void do_conv(buffer<float, 2> in, buffer<float, 2> out) {queue myQueue;

14.
15.

myQueue.submit([&](handler& cgh) {16.

accessor in_acc { in, cgh, read_only };17.

accessor out_acc { out, cgh, write_only };

18.
19.

// 畳み込み係数を一定に設定

20.

// これにより、リテラルとして利用可能な係数が特定のカーネルに構築されます

21.

cgh.set_specialization_constant<coeff_id>(get_coefficients());

22.
23.
24.

cgh.parallel_for<class Convolution>(in.get_range(), [=](item<2> item_id, kernel_handler h) {25.

float acc = 0;26.

coeff_t coeff = h.get_specialization_constant<coeff_id>();27.

for (int i = -1; i <= 1; i++) {

28.
29.
30.

if (item_id[0] + i < 0 || item_id[0] + i >= in_acc.get_range()[0])continue;for (int j = -1; j <= 1; j++) {第 4 章 SYCL プログラミング・インターフェイス | 271

SYCL 2020 リビジョン 6 - 4.10 ホストタスク31.

if (item_id[1] + j < 0 || item_id[1] + j >= in_acc.get_range()[1])32.

continue;

33.

// JIT は coeff.get() によって返される配列の34.

// すべての値を確認できます35.

acc += coeff[i + 1][j + 1] *36.

in_acc[item_id[0] + i][item_id[1] + j];

37.

}

38.

}

39.

out_acc[item_id] = acc;

40.
41.

});
});

42.
43.

myQueue.wait();44.

}

4.10. ホストタスク
4.10.1. 概要
ホストタスクは、SYCL ランタイムでスケジュールされるネイティブ C++ 呼び出し可能なオブジェクトです。ホストタスクは、ホスト・タス
ク・コマンドによりコマンドグループを介してキューに送信されます。
ホスト・タスク・コマンドがキューに送信されると、カーネル起動コマンドや非同期コピーなどほかのコマンドとのデータ依存関係に基づいてスケジュールされ、3.8.1 節で定義されるようにコマンドグループにアタッチされたアクセサーによって生じる要件が解決されます。
ホストタスクは、SYCL カーネル関数としてコンパイルされず、SYCL ランタイムによって直接呼び出されるため、SYCL カーネル関数の制限は適用されず任意の C++ コードに含めることができます。
ホストタスクでアクセサーを取得することは許可されていますが、参照セマンティクス (4.5.2 節を参照) を使用する SYCL クラスの取得と利用の動作は未定義です。
ホストタスクは任意のキューにエンキューでき、キューに関連付けられるデバイスにかかわりなく呼び出し可能オブジェクトは SYCL
ランタイムから直接呼び出されます。
ホストタスクは、handler クラスの host_task メンバー関数を介してキューにエンキューされます。関連するコマンドグループを送信して返されるイベントは、提供された C++ 呼び出し可能オブジェクトが返されると完了状態 (info::event_command_status::completeのステータスに対応) となります。ホストタスクの実行中にスローされたキャッチされていない例外は、4.13.1.1 節の説明に従って処理できる非同期エラーに変更されます。
ホストタスクは、オプションの interop_handle パラメーターを介して、ホストタスクを実行するキューに関連付けられたネイティブ・
バックエンド・オブジェクト、キューに関連付けられているコンテキスト、キューに関連付けられているデバイス、および呼び出し可能なオブジェクトでキャプチャーされているアクセサーと相互運用するために利用できます。
これにより、ホストタスクを SYCL ランタイムのスケジュール内で任意の C++ コードを実行するタスクとして、または SYCL ランタイムのスケジュール内のある時点で相互運用を実行するタスクとして、2 つの用途で使用できます。
前者の利用ケースでは、target::host_task を使用してバッファーアクセサーを作成するか、image_target::host_task を使用してイ
メージアクセサーを作成します。これにより、ホストタスクの実行中にバッファーまたはイメージアクセサーを使用できるようになります。

272 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.10 ホストタスク
後者の場合、target::device または target::constant_buffer を使用してバッファーアクセサーを構築するか、image_target::deviceを使用してイメージアクセサーを構築します。これにより、ホストタスクの送信に使用されるキューに関連付けられているデバイスで、バッファーもしくはイメージを利用できるようになり、interop_handle クラスで提供される相互運用メンバー関数を介してアクセスできます。
ローカルアクセサーはホストタスク内では使用できません。
1.

namespace sycl {2.
3.

class interop_handle {4.

private:5.
6.

interop_handle( __unspecified__ );7.
8.

public:9.
10.

interop_handle() = delete;

11.
12.

backend get_backend() const noexcept;

13.
14.

template <backend Backend, typename DataT, int Dims, access_mode AccessMode,15.

target AccessTarget, access::placeholder IsPlaceholder>16.

backend_return_t<Backend, buffer<DataT, Dims>>

17.

get_native_mem(const accessor<DataT, Dims, AccessMode, AccessTarget,

18.

IsPlaceholder>& bufferAccessor) const;

19.
20.

template <backend Backend, typename DataT, int Dims, access_mode AccMode>

21.

backend_return_t<Backend, unsampled_image<Dims>>

22.

get_native_mem(

23.

const unsampled_image_accessor<DataT, Dims, AccMode, image_target::device>& imageAcc) const;

24.
25.

template <backend Backend, typename DataT, int Dims>

26.

backend_return_t<Backend, sampled_image<Dims>>

27.

get_native_mem(

28.

const sampled_image_accessor<DataT, Dims, image_target::device>& imageAcc)

29.

const;

30.
31.

template <backend Backend>

32.

backend_return_t<Backend, queue> get_native_queue() const;

33.
34.

template <backend Backend>

35.

backend_return_t<Backend, device> get_native_device() const;

36.
37.

template <backend Backend>

38.

backend_return_t<Backend, context> get_native_context() const;

39.
40.

};

41.
42.
43.

class handler {
...

44.
45.

public:

第 4 章 SYCL プログラミング・インターフェイス | 273

SYCL 2020 リビジョン 6 - 4.10 ホストタスク
46.
47.

template <typename T>

48.

void host_task(T&& hostTaskCallable);

49.
50.
51.

...
};

52.
53.

} // namespace sycl

4.10.2. クラス interop_handle
interop_handle クラスは、ホストタスクと関連するデバイスおよびコンテキストを呼び出す際に使用されるキューを抽象化します。また、ホストタスクが呼び出されたときの SYCL ランタイムの依存関係モデルの状態を表します。
interop_handle クラスは、相互運用の目的でホストタスクを利用できるように、キュー、デバイス、コンテキスト、および呼び出されている呼び出し可能オブジェクトでキャプチャーされたバッファーまたはイメージに関連付けられたネイティブ・バックエンド・オブジェク
トへのアクセスを提供します。
interop_handle は、SYCL ランタイムによってのみ構築でき、ユーザーコードからは構築できません。
1.

class interop_handle;

4.10.2.1. コンストラクター1.

private:2.
3.

interop_handle(__unspecified__);// (1)

4.
5.

public:6.
7.
1.

interop_handle() = delete;// (2)SYCL ランタイムが interop_handle を構築できるようする引数が指定されていないプライベート実装定義のコンストラ
クター。

2.

明示的に削除されるデフォルト・デストラクター。

4.10.2.2. メンバー関数
1.

backend get_backend() const noexcept;

1.

戻り値: この interop_handle に関連付けられたキューに関連する SYCL バックエンドを識別する backend を返します。

4.10.2.3. テンプレート・メンバー関数 get_native_*
1.

// SPDX-License-Identifier: MIT

2.
3.
4.

template <backend Backend, typename DataT, int Dims, access_mode AccMode,target AccTarget, access::placeholder IsPlaceholder>5.

backend_return_t<Backend, buffer<DataT, Dims>>

6.

get_native_mem(const accessor<DataT, Dims, AccMode, AccTarget,

7.

IsPlaceholder>& bufferAcc) const;

274 | 第 4 章 SYCL プログラミング・インターフェイス// (1)

SYCL 2020 リビジョン 6 - 4.10 ホストタスク
8.
9.

template < backend Backend, typename DataT, int Dims, access_mode AccMode>10.

backend_return_t <Backend, unsampled_image<Dims>>

11.

get_native_mem (12.

// (2)

const unsampled_image_accessor<DataT, Dims, AccMode, image_target::device>& imageAcc) const;

13.
14.

template <backend Backend, typename DataT, int Dims>

15.

backend_return_t<Backend, sampled_image<Dims>>

16.

get_native_mem(17.

// (3)

const sampled_image_accessor<DataT, Dims, image_target::device>& imageAcc) const;

18.
19.

template <backend Backend>

20.

backend_return_t<Backend, queue> get_native_queue() const;// (4)

21.
22.

template <backend Backend>

23.

backend_return_t<Backend, device> get_native_device() const;// (5)

24.
25.

template <backend Backend>

26.

backend_return_t<Backend, context> get_native_context() const;

1.

条件: buffer を取得するオプションの相互関数 get_native が利用可能で、AccTarget が target::device である場合にの// (6)

み使用できます。
戻り値: アクセサー bufferAcc のバッファーに関連付けられたネイティブ・バックエンド・オブジェクトを返します。返されるネイティブ・バックエンド・オブジェクトは、SYCL ランタイムの依存関係モデル内のメモリー状態を示し、関連する SYCL
バックエンドに適した方法で利用できます。ホストタスクのスコープ外でネイティブ・バックエンド・オブジェクトを使用すると未定義の動作となります。
スロー: アクセサー bufferAcc がホストタスクを含むコマンドグループに登録されていない場合、errc::invalid エラーコー
ドで例外をスローします。Backend != get_backend() である場合、errc::backend_mismatch エラーコードで例外をスローする必要があります。
2.

条件: unsampled_image を取得するオプションの相互関数 get_native が使用可能である場合にのみ利用できます。
戻り値: アクセサー imageAcc に関連付けられた SYCL アプリケーションの相互運用性ネイティブ・バックエンド・オブジェ
クトを返します。返される ネイティブ・バックエンド・オブジェクトは、SYCL ランタイムの依存関係モデル内のメモリー状態を示し、関連する SYCL バックエンドに適した方法で利用できます。ホストタスクのスコープ外でネイティブ・バックエンド・
オブジェクトを使用すると未定義の動作となります。
スロー: アクセサー imageAcc がホストタスクを含むコマンドグループに登録されていない場合、errc::invalid エラーコー
ドで例外をスローします。

3.

条件: sampled_image を取得するオプションの相互関数 get_native が使用可能である場合にのみ利用できます。
戻り値: アクセサー imageAcc の sampled_image に関連付けられたネイティブ・バックエンド・オブジェクトを返します。
返されるネイティブ・バックエンド・オブジェクトは、SYCL ランタイムの依存関係モデル内のメモリー状態を示し、関連する
SYCL バックエンドに適した方法で利用できます。ホストタスクのスコープ外でネイティブ・バックエンド・オブジェクトを使用すると未定義の動作となります。
スロー: アクセサー imageAcc がホストタスクを含むコマンドグループに登録されていない場合、errc::invalid エラーコー
ドで例外をスローします。Backend != get_backend() である場合、errc::backend_mismatch エラーコードで例外をスローする必要があります。

第 4 章 SYCL プログラミング・インターフェイス | 275

SYCL 2020 リビジョン 6 - 4.10 ホストタスク
4.

条件: queue を取得するオプションの相互関数 get_native が使用可能である場合にのみ利用できます。
戻り値: ホストタスクが送信されたキューに関連付けられたネイティブ・バックエンド・オブジェクトを返します。コマンドグ
ループがセカンダリー・キューに送信され、フォールバック・キューがトリガーされた場合、interop_handle に関連付けられるキューはフォールバック・キューでなければなりません。返されるネイティブ・バックエンド・オブジェクトは、関連する
SYCL バックエンドに適した方法で利用可能な状態である必要があります。ホストタスクのスコープ外でネイティブ・バック
エンド・オブジェクトを使用すると未定義の動作となります。
スロー: Backend != get_backend() である場合、errc::backend_mismatch エラーコードで例外をスローする必要があります。

5.

条件: device を取得するオプションの相互関数 get_native が使用可能である場合にのみ利用できます。
戻り値: ホストタスクが送信されたキューに関連付けられているデバイスに関連するネイティブ・バックエンド・オブジェクトを返します。返されるネイティブ・バックエンド・オブジェクトは、関連する SYCL バックエンドに適した方法で利用可能な状態である必要があります。ホストタスクのスコープ外でネイティブ・バックエンド・オブジェクトを使用すると未定義の動作となります。
スロー: Backend != get_backend() である場合、errc::backend_mismatch エラーコードで例外をスローする必要があります。

6.

条件: context を取得するオプションの相互運用関数 get_native が使用可能である場合にのみ利用できます。
戻り値: ホストタスクが送信されたキューに関連付けられているコンテキストに関連するネイティブ・バックエンド・オブジェ
クトを返します。返されるネイティブ・バックエンド・オブジェクトは、関連する SYCL バックエンドに適した方法で利用可能な状態である必要があります。ホストタスクのスコープ外でネイティブ・バックエンド・オブジェクトを使用すると未定義の動作となります。
スロー: Backend != get_backend() である場合、errc::backend_mismatch エラーコードで例外をスローする必要があります。

4.10.3. handler クラスへの追加
ここでは、ホストタスクで使用されるコマンド・グループ・ハンドラー・クラスのメンバー関数について説明します。
1.

class handler {

2.

...

3.
4.

public:5.

template <typename T>

6.

void host_task(T&& hostTaskCallable); // (1)

7.
8.

...

9.

};

1.

効果: 実装定義のコマンドを SYCL ランタイムにエンキューして、hostTaskCallable を一度だけ呼び出します。SYCL ラン
タイムにエンキューされたほかのコマンドに関連する hostTaskCallable 呼び出しのスケジュールは、3.8.1 節で説明する
依存関係モデルに従う必要があります。std::is_invocable_v<T, interop_handle> が true である場合、interop_handle
オブジェクトを初期化して、呼び出されたときに hostTaskCallable へ渡します。それ以外では、hostTaskCallable を引数なし関数として呼び出します。

276 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル

4.11. カーネルバンドル
カーネルバンドルは、SYCL アプリケーションにいくつかの機能を提供します。オンラインコンパイルをサポートする実装では、デバイ
スコードのオフラインコンパイルを細かく制御できます。例えば、アプリケーションは実装のデフォルト動作 (カーネルが送信されるまでコンパイルしない) に依存せず、カーネルバンドルを使用してアプリケーション実行中の特定の時間 (初期化など) にカーネルをコンパイルできます。
カーネルバンドルは、アプリケーションがカーネルの特殊化定数値をデバイスへ送信する前に設定することもできます。これにより効率が向上することもあります。
カーネルバンドルは、アプリケーションがカーネル内部を調査する方法を提供します。例えば、アプリケーションが特定のデバイスで実行されると、バンドルを使用してカーネルの work-group サイズを照会できます。
最後に、カーネルバンドルは、バックエンドおよびデバイス固有の機能との相互運用のため拡張ポイントを提供します。このいくつかの例には、デバイス固有のビルトインカーネルの呼び出し、ベンダー固有のオプションによるカーネルコードのオンラインコンパイル、およびバックエンド API で作成されたカーネルとの相互運用などがあります。

4.11.1. 概要
カーネルバンドルはコンテキストに関連付けられ、各デバイスが同じコンテキストに関連する複数のデバイスで実行できるカーネルのセットを表す高レベルの抽象化です。バンドルの取得方法に応じて、SYCL アプリケーションのすべての SYCL カーネル関数、またはそれらの特定のサブセットを表すことができます。
カーネルバンドルは、1 つ以上のデバイスイメージで構成され、コンパイルやリンクの分割できない単位です。SYCL ランタイムは、デバイスイメージで表現されるカーネルをコンパイルおよびリンクする場合、デバイスイメージが表すほかのカーネルもコンパイルまたはリンクする必要があります。デバイスイメージが一度コンパイルおよびリンクわれると、そのデバイスイメージを表現するほかのカー
ネルは、さらにコンパイルまたはリンクすることなく呼び出し可能です。
バンドルを表現する SYCL カーネル関数は、バンドルのデバイスイメージの少なくとも 1 つに存在する必要があります。しかし、各デバ
イスイメージにバンドルが表現するすべてのカーネル関数が含まれている必要はありません。カーネル関数がデバイスイメージにグ
ループ化される粒度は実装依存です。
デバイスイメージの目的を説明するため、仮定とする実装では、アプリケーションのカーネル関数を SPIR-V 形式とネイティブ・デバイス・コード形式の両方で表現できます。この例の事前コンパイル (AOT) は、特定のデバイス向けのネイティブコードでデバイスイメージを生成し、ほかのデバイスでも使用できるよう SPIR-V デバイスイメージも生成します。このような実装では、特定のカーネル関数が複数のデバイスイメージで表現される可能性があることに注意してください。
実装は、すべての変換ユニットのすべてのカーネル関数を 1 つのデバイスイメージにグループ化するか、それぞれのカーネル関数を個別のデバイスイメージで表すか、または別の方法でカーネル関数をグループ化するか選択できます。
カーネルバンドルに関連付けられたそれぞれのデバイスには、少なくとも 1 つの互換性のあるデバイスイメージが必要であり、実装はデバイス上でイメージ内のカーネル関数を直接呼び出すか、実装がデバイスイメージでカーネル関数を呼び出すことができる形式に変換できます。
この定義により、バンドル内の各カーネル関数は、バンドルに関連付けられたデバイスの少なくとも 1 つで呼び出し可能である必要があります。ただし、バンドル内のすべてのカーネル関数が関連付けられたすべてのデバイスで呼び出し可能である必要はありません。

第 4 章 SYCL プログラミング・インターフェイス | 277

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル

バンドルに関連付けられているすべてのデバイスでカーネル関数を呼び出せない理由の 1 つには、カーネルがオプションのデバイス機能を使用する場合があります。これらの機能は、バンドル内の一部のデバイスでのみ利用可能であることがあります。
オプションのデバイス機能を利用すると、それらの機能の表現の仕方に応じて、実装がカーネルをデバイスイメージにグループ化するのに影響する場合があります。例えば、オプションの機能が SPIR-V で表現され、ターゲットデバ
イスがその機能をサポートしていないため、その SPIR-V のネイティブコードへの変換に失敗する実装について考えてみます。そのような実装では、オプション機能を利用するカーネルを、その機能を利用しないカーネルと同じデバ
イスイメージにグループ化してはなりません。デバイスイメージは分割できないコンパイル単位であるため、デバイ
ス D1 でサポートされない機能を使用するカーネル K2 と同じデバイスイメージに K1 がグループ化されると、カーネル K1 がデバイス D1 で呼び出されるとコンパイルに失敗します。
オプションのデバイス機能の詳細については、5.7 節を参照してください。
SYCL アプリケーションは、get_kernel_bundle() フリー関数のオーバーロードの 1 つを呼び出すことでカーネルバンドルを取得できます。特定のバックエンドは、表現の異なるバンドルを取得するため追加メカニズムを提供する場合があります。これがサポートされる
場合、バックエンドの仕様書に詳細が示されます。
カーネルバンドルが取得されると、コンパイル、リンク、および結合向けのいくつかのフリー関数があります。バンドルがコンパイルおよびリンクされると、アプリケーションは 4.9.4.4 節で説明されるように handler::use_kernel_bundle() を呼び出すことで、バンドルからカーネルを起動することができます。

4.11.2. 概要
1.

namespace sycl {2.
3.

enum class bundle_state : /* 未定義 */ {4.

input,

5.

object,6.
7.

executable
};

8.
9.
10.

class kernel_id { /* ... */ };

11.
12.

template<bundle_state State>

13.

class kernel_bundle { /* ... */ };

14.
15.
16.

template <typename KernelName>

17.

kernel_id get_kernel_id();

18.
19.

std::vector<kernel_id> get_kernel_ids();

20.
21.
22.

template<bundle_state State>

23.

kernel_bundle<State> get_kernel_bundle(const context& ctxt);

24.
25.

template<bundle_state State>

26.

kernel_bundle<State> get_kernel_bundle(const context& ctxt,

278 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
27.

const std::vector<kernel_id>& kernelIds);

28.
29.

template<typename KernelName, bundle_state State>30.

kernel_bundle<State> get_kernel_bundle(const context& ctxt);

31.
32.

template<bundle_state State>

33.

kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs);

34.
35.

template<bundle_state State>36.

kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs,

37.

const std::vector<kernel_id>& kernelIds);

38.
39.

template<typename KernelName, bundle_state State>

40.

kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs);

41.
42.

template<bundle_state State, typename Selector>

43.

kernel_bundle<State> get_kernel_bundle(const context& ctxt, Selector selector);

44.
45.

template<bundle_state State, typename Selector>

46.

kernel_bundle<State> get_kernel_bundle(const context&ctxt, const std::vector<device>& devs,

47.

Selector selector);

48.
49.
50.

template<bundle_state State>

51.

bool has_kernel_bundle(const context& ctxt);

52.
53.

template<bundle_state State>

54.

bool has_kernel_bundle(const context& ctxt, const std::vector<kernel_id>& kernelIds);

55.
56.

template<typename KernelName, bundle_state State>

57.

bool has_kernel_bundle(const context& ctxt);

58.
59.

template<bundle_state State>

60.

bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs);

61.
62.

template<bundle_state State>

63.

bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs,

64.

const std::vector<kernel_id>& kernelIds);

65.
66.

template<typename KernelName, bundle_state State>

67.

bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs);

68.
69.
70.

bool is_compatible(const std::vector<kernel_id>&kernelIds, const device& dev);

71.
72.

template<typename KernelName>

73.

bool is_compatible(const device& dev);

74.
75.
76.

template<bundle_state State>77.

kernel_bundle<State> join(const std::vector<kernel_bundle<State>>& bundles);78.

第 4 章 SYCL プログラミング・インターフェイス | 279

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
79.
80.

kernel_bundle<bundle_state::object>

81.

compile(const kernel_bundle<bundle_state::input>& inputBundle,

82.

const property_list& propList = {});

83.
84.

kernel_bundle<bundle_state::object>

85.

compile(const kernel_bundle<bundle_state::input>& inputBundle,

86.

const std::vector<device>& devs,

87.

const property_list& propList = {});

88.
89.

kernel_bundle<bundle_state::executable>90.

link(const kernel_bundle<bundle_state::object>& objectBundle,

91.

const property_list& propList = {});

92.
93.

kernel_bundle<bundle_state::executable>

94.

link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,

95.

const property_list& propList = {});

96.
97.

kernel_bundle<bundle_state::executable>98.

link(const kernel_bundle<bundle_state::object>& objectBundle,

99.

const std::vector<device>& devs,

100.

const property_list& propList = {});

101.
102.

kernel_bundle<bundle_state::executable>

103.

link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,104.

const std::vector<device>& devs,

105.

const property_list& propList = {});

106.
107.

kernel_bundle<bundle_state::executable>

108.

build(const kernel_bundle<bundle_state::input>& inputBundle,

109.

const property_list& propList = {});

110.
111.

kernel_bundle<bundle_state::executable>

112.

build(const kernel_bundle<bundle_state::input>& inputBundle,

113.

const std::vector<device>& devs,

114.

const property_list& propList = {});

115.
116.

} // namespace sycl

4.11.3. 固定機能のビルトインカーネル
SYCL は、SYCL バックエンドで固定機能を非プログラマブルなビルトイン関数として提供できます。これらのビルトインカーネルの可用性と動作はバックエンド固有であり、SYCL 実行モデルとメモリーモデルに従う必要はありません。基本的なインターフェイスはすべてのバックエンドで共通です。

4.11.4. バンドルの状態
カーネルバンドルは、bundle_state と呼ばれる列挙型クラスで示される 3 つの異なるバンドル状態のいずれかになります。表 135 に
3 つの状態のセマンティクスを示します。

280 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
状態は遷移していきます。bundle_state::input 内のバンドルは、バンドルのオンラインコンパイルによって bundle_state::object に変換できます。bundle_state::object 内のバンドルは、オンラインリンクによって bundle_state::executable に変換できます。
バンドル状態の遷移が維持され、それぞれの状態のバンドルが指定されるように動作する限り、各実装は、「オンラインコンパイル」と「オンラインリンク」を自由に定義できます。
実装が bundle_state::input または bundle_state::object 状態のカーネルを公開する必要があるという要件はありません。実際には、実装はこれらの状態のカーネルを公開することはできますが、ほかの状態は公開できません。例えば、この振る舞いは事前コンパイル(AOT) の実装固有オプションで制御できます。
これらの状態で公開されないカーネルは、アプリケーションによってオンラインまたはオフラインコンパイルでリンクを行うことができません。
SYCL アプリケーションで定義されるすべてのカーネルは、bundle_state::executable 状態で公開する必要があります。これは、デバ
イスがカーネルを呼び出すことができる唯一の状態であるためです。デバイスのビルトインカーネルも bundle_state::executable 状
態で公開されます。
アプリケーションがデバイス D の bundle_state::input でバンドル状態を公開する場合、実装はデバイス D のオンライン・コンパイ
ラーを提供する必要があります。つまり、アプリケーションがデバイスの bundle_state::input 状態でバンドルの取得に成功した場合、
aspect::online_compiler を明示的にテストする必要はありません。同様に、実装がデバイス D の bundle_state::object 状態でバンドルを公開する場合、デバイス D のオンラインリンカーを提供しなければなりません。
表 135.可能なバンドル状態の列挙
バンドルの状態

説明

bundle_state::input

カーネルバンドル内のデバイスイメージは、カーネルを呼び出す
前にコンパイルしてリンクする必要があります。例えば、実装はこの状態の中間言語形式で保存されているデバイスイメージ、またはソースコードの文字列として保存されるデバイスイメージに適用できます。

bundle_state::object

カーネルバンドル内のデバイスイメージは、カーネルを呼び出す
前にてリンクする必要があります。

bundle_state::executable

カーネルバンドル内のデバイスイメージは、デバイスが呼び出し可能な形式になっています。例えば、実装はデバイスのネイティブ
コードにコンパイルされたデバイスイメージにこの状態を適用できます。

4.11.5. カーネル識別子
カーネルバンドルに関連するいくつかの関数は、カーネルの識別子である kernel_id タイプの入力パラメーターを受け入れます。
kernel_id クラスの概要とメンバー関数の説明を以下に示します。さらに、このクラスが提供する共通特殊メンバー関数と共通メンバー関数については、4.5.2 節の表 7 と表 8 を参照してください。
共通の参照セマンティクスを持つほかのすべての SYCL オブジェクトと同様に、カーネル識別子は等価比較可能です。2 つの kernel_id
オブジェクトは、同じアプリケーションのカーネル、または同じデバイス組込みカーネルを参照する場合にのみ、等価比較されます。
このクラスにはパブリック・デフォルト・コンストラクターがありません。

第 4 章 SYCL プログラミング・インターフェイス | 281

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
1.

namespace sycl {2.
3.

class kernel_id {4.

public:5.

kernel_id() = delete;

6.
7.
8.

const char* get_name() const noexcept;
};

9.
10.

} // namespace sycl

const char* get_name() const noexcept;
戻り値: カーネル名を含む実装で定義された null で終了する文字列を返します。この名称がすべてのカーネルで一意である保証はありません。また、アプリケーションが実行される間、この名称が永続的である保証もありません。名称を含むメモリーの有効期間は未定義です。
実際には、名称に関連付けられたカーネルが動的ライブラリーでない限り、その名前を含むメモリーの有効期間はアプリケーションが終了するまでになります。しかし、動的ライブラリーがアンロードされるとメモリーの有効期間が終了する可能性があります。

4.11.6. カーネル識別子を取得する
アプリケーションは、次のフリー関数のいずれかを呼び出すことで、アプリケーションで定義されるカーネルの識別子を取得できます。
また、info::device::built_in_kernel_ids によってデバイスの照会を行うことで、デバイスのビルトインカーネルの識別子を取得できます。
template <typename KernelName>kernel_id get_kernel_id();
前提条件: テンプレート・パラメーター KernelName は、SYCL アプリケーションで定義されるカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名がないため、ラムダ関数として定義されたカーネルはこの関数を使用して識別子を取得するため、カーネル起動コマンドで KernelName を指定する必要があります。定義されていない KernelName の get_kernel_id() を呼び出すアプリケーションは不正な形式であり、実装は診断を行う必要があります。
戻り値: KernelName に関連付けられたカーネルの識別子を返します。
std::vector<kernel_id> get_kernel_ids();
戻り値: SYCL アプリケーションで定義されたすべてのカーネル識別子を持つベクトルを返します。これには、デバイスのビルトインカー
ネルの識別子は含まれません。

4.11.7. カーネルバンドルを取得する
SYCL アプリケーションは、フリー関数 get_kernel_bundle() のオーバーロードの 1 つを呼び出すことでカーネルバンドルを取得できます。実装は、事前コンパイルによって作成されたデバイスイメージで構成されるバンドルを返すことがあります。また、要求された状態のバンドルのデバイスイメージを作成するため、オンライン・コンパイラーやリンカーを呼び出す場合もあります。また、バンドルにはデバイスのビルトインカーネルを表すデバイスイメージが含まれることもあります。
ｇet_kernel_bundle() を使用して bundle_state::object または bundle_state::executable のカーネルバンドルを取得する場合、バンドル内の特殊化定数はすべてデフォルト値になります。

282 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
template<bundle_state State>kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs);
戻り値: State 状態のカーネルバンドルを返します。これには、devs のデバイスと互換性のあるアプリケーション内のすべてのカーネルが含まれます。これには、デバイスのビルトインカーネルは含まれません。バンドルの関連デバイスセットは devs (重複するデバイスを削除した状態)です。
実装は、bundle_state::input または bundle_state::object のすべてのカーネルを表すとは限らないため、これらの状態でこの関数を呼び出すと、アプリケーションのカーネルが部分的に欠落したバンドルが返されることがあります。
スロー:• devs のデバイスのいずれかがコンテキスト ctxt に含まれるデバイスではない場合、または ctxt 内のデバイスの下位デバイスではない場合、errc::invalid エラーコードで例外をスローします。

• devs ベクトルが空である場合、errc::invalid エラーコードで例外をスローします。
• State が bundle_state::input であり、devs のデバイスに aspect::online_compiler が存在しない場合、errc::invalid エラー
コードで例外をスローします。

• State が bundle_state::object であり、devs のデバイスに aspect::online_linker が存在しない場合、errc::invalid エラーコー
ドで例外をスローします。

• State が bundle_state::object または bundle_state::executable であり、実装がオンラインコンパイルまたはリンクを行う必要がある場合、およびオンラインコンパイルやリンクに失敗すると errc::build エラーコードで例外をスローします。
template<bundle_state State>kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs,
const std::vector<kernel_id>& kernelIds);
戻り値: devs 内のデバイスの少なくとも 1 つと互換性のあるデバイスイメージを含む State 状態のカーネルバンドルを返します。さらに、少なくとも 1 つの指定された識別子を持つカーネルのデバイスイメージのみが含まれるようフィルターされます。これらの識別子
は、アプリケーションで定義されるカーネルまたはデバイスのビルトインカーネルを表す場合と、それら 2 つの組み合わせを表す場合があります。デバイスイメージには多くのカーネルがグループ化される可能性があるため、返されるバンドルには kernelIds で要求されるカーネル以外も含まれることがあります。バンドルの関連デバイスセットは devs (重複するデバイスを削除した状態) です。
実装は、bundle_state::input または bundle_state::object のすべてのカーネルを表すとは限らないため、これらの状態でこの関数を
呼 び 出 す と 、 kernelIds の カ ー ネ ル が 部 分 的 に 欠 落 し た バ ン ド ル が 返 さ れ る こ と が あ り ま す 。 ア プ リ ケ ー シ ョ ン は
kernel_bundle::has_kernel() でこれをテストできます。
スロー:• kernelIds で識別されるカーネルのいずれかが devs のすべてのデバイスと互換性がない場合、errc::invalid エラーコードで例外がスローされます。

• devs のデバイスのいずれかがコンテキスト ctxt に含まれるデバイスではない場合、または ctxt 内のデバイスの下位デバイスではない場合、errc::invalid エラーコードで例外をスローします。

• devs ベクトルが空である場合、errc::invalid エラーコードで例外をスローします。
• State が bundle_state::input であり、devs のデバイスに aspect::online_compiler が存在しない場合、errc::invalid エラー
コードで例外をスローします。

• State が bundle_state::object であり、devs のデバイスに aspect::online_linker が存在しない場合、errc::invalid エラーコー
ドで例外をスローします。

• State が bundle_state::object または bundle_state::executable であり、実装がオンラインコンパイルまたはリンクを行う必要がある場合、およびオンラインコンパイルやリンクに失敗すると errc::build エラーコードで例外をスローします。

第 4 章 SYCL プログラミング・インターフェイス | 283

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
template<bundle_state State, typename Selector>
kernel_bundle<State> get_kernel_bundle(const context& ctxt,
const std::vector<device>& devs,
Selector selector);
前提条件: selector は、戻り値を bool に変換可能で、パラメーターが const device_image<State>& の単項プレディケートでなければなりません。
効果: プレディケート関数 selector は、devs のデバイスの少なくとも 1 つの互換性がある State 状態のアプリケーションで、デバイス
イメージごとに一度呼び出されます。関数の戻り値は、デバイスイメージが新しいカーネルバンドルに含まれるかどうかを決定します。
Selector は、アプリケーションが定義するカーネルを含むデバイスイメージに対してのみ呼び出され、デバイスのビルトインカーネル
を含むデバイスイメージでは呼び出されません。
戻り値: Selector が true を返すすべてのデバイスイメージを含む State 状態のカーネルバンドルを返します。バンドルに関連付けられているデバイスのセットは devs (重複するデバイスは削除された状態) です。
スロー:• devs のデバイスのいずれかがコンテキスト ctxt に含まれるデバイスではない場合、または ctxt 内のデバイスの下位デバイスではない場合、errc::invalid エラーコードで例外をスローします。

• devs ベクトルが空である場合、errc::invalid エラーコードで例外をスローします。
• State が bundle_state::input であり、devs のデバイスに aspect::online_compiler が存在しない場合、errc::invalid エラー
コードで例外をスローします。

• State が bundle_state::object であり、devs のデバイスに aspect::online_linker が存在しない場合、errc::invalid エラーコー
ドで例外をスローします。
この関数は、アプリケーションがバックエンド固有の基準に基づいてデバイスイメージを選択できるように、バックエンド固有の API と組み合わせて使用することを意図しています。
この関数は、デバイスイメージを State 状態に変換するためオンライン・コンパイラーやリンカーを呼び出しません。
アプリケーションがデバイスイメージを選択して特定の状態にコンパイルおよびリンクする場合、compile() またはlink() を呼び出し、オプションで複数のバンドルを join() で結合できます。
template<bundle_state State>// (1)

kernel_bundle<State> get_kernel_bundle(const context& ctxt);
template<bundle_state>// (2)

kernel_bundle<State> get_kernel_bundle(const context& ctxt,
const std::vector<kernel_id>& kernelIds);
template<bundle_state State, typename Selector> // (3)kernel_bundle<State> get_kernel_bundle(const context& ctxt, Selector selector);1.

get_kernel_bundle<State>(ctxt, ctxt.get_devices()) と同等です。

2.

get_kernel_bundle<State>(ctxt, ctxt.get_devices(), kernelIds) と同等です。

3.

get_kernel_bundle<State>(ctxt, ctxt.get_devices(), selector) と同等です。

template<typename KernelName, bundle_state State>// (1)

kernel_bundle<State> get_kernel_bundle(const context& ctxt);

284 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
template<typename KernelName, bundle_state State>// (2)

kernel_bundle<State> get_kernel_bundle(const context& ctxt, const std::vector<device>& devs);
前提条件: テンプレート・パラメーター KernelName は、SYCL アプリケーションで定義されるカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名が存在せず、ラムダ関数として定義されたカーネルはこの関数を使用するため、カーネル
起動コマンドで KernelName を指定する必要があります。定義されていない KernelName の関数を呼び出すアプリケーションは不正な形式であり、実装は診断を行う必要があります。
1.

get_kernel_bundle<State>(ctxt, ctxt.get_devices(), {get_kernel_id<KernelName>()}) と同等です。

2.

get_kernel_bundle<State>(ctxt, devs, {get_kernel_id<KernelName>()}) と同等です。

4.11.8. カーネルバンドルの存在を照会する
get_kernel_bundle() のほとんどのオーバーロードには、要求された特性を持つカーネルバンドルがあるかどうかを確認するフリー関
数 has_kernel_bundle() のオーバーロードがあります。
template<bundle_state State>bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs);
戻り値: 次のすべてが true である場合にのみ true となります。

• アプリケーションは、devs のデバイスの少なくとも 1 つと互換性のあるカーネルを定義し、State 状態のデバイスイメージを表現します。

• State が bundle_state::input である場合、devs のすべてのデバイスは aspect::online_compiler を持ちます。
• State が bundle_state::object である場合、devs のすべてのデバイスは aspect::online_linker を持ちます。
スロー:• devs のデバイスのいずれかがコンテキスト ctxt に含まれるデバイスではない場合、または ctxt 内のデバイスの下位デバイスではない場合、errc::invalid エラーコードで例外をスローします。

• devs ベクトルが空である場合、errc::invalid エラーコードで例外をスローします。
template<bundle_state State>bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs,
const std::vector<kernel_id>& kernelIds);
戻り値: 次のすべてが true である場合にのみ true となります。

• kernelIds の各カーネルは、State 状態のデバイスイメージを表現できます。
• kernelIds の各カーネルは、devs の少なくとも 1 つのデバイスと互換性があります。
• State が bundle_state::input である場合、devs のすべてのデバイスは aspect::online_compiler を持ちます。
• State が bundle_state::object である場合、devs のすべてのデバイスは aspect::online_linker を持ちます。
スロー:• devs のデバイスのいずれかがコンテキスト ctxt に含まれるデバイスではない場合、または ctxt 内のデバイスの下位デバイスではない場合、errc::invalid エラーコードで例外をスローします。

• devs ベクトルが空である場合、errc::invalid エラーコードで例外をスローします。
template<bundle_state State>// (1)

bool has_kernel_bundle(const context& ctxt);

第 4 章 SYCL プログラミング・インターフェイス | 285

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
template<bundle_state>// (2)

bool has_kernel_bundle(const context& ctxt, const std::vector<kernel_id>1.

has_kernel_bundle(ctxt, ctxt.get_devices()) と同等です。

2.

has_kernel_bundle<State>(ctxt, ctxt.get_devices(), kernelIds) と同等です。

template<typename KernelName, bundle_state State> // (1)bool has_kernel_bundle(const context& ctxt);
template<typename KernelName, bundle_state State> // (2)bool has_kernel_bundle(const context& ctxt, const std::vector<device>& devs);
前提条件: テンプレート・パラメーター KernelName は、SYCL アプリケーションで定義されるカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名が存在せず、ラムダ関数として定義されたカーネルはこの関数を使用するため、カーネル
起動コマンドで KernelName を指定する必要があります。定義されていない KernelName の関数を呼び出すアプリケーションは不正な形式であり、実装は診断を行う必要があります。
1.

has_kernel_bundle<State>(ctxt, {get_kernel_id<KernelName>()}) と同等です。

2.

has_kernel_bundle<State>(ctxt, devs, {get_kernel_id<KernelName>()}) と同等です。

4.11.9. カーネルがデバイスと互換性があるか照会する
アプリケーションは次のフリー関数を使用して、特定のカーネルがデバイスと互換性を持つかテストできます。アプリケーションで定義されるカーネルは、次の場合を除いてデバイスと互換性があります。

• 5.7 節で説明されるように、デバイスでサポートされないオプション機能を使用する。
• または、5.8.1 節で説明されるように、デバイスがサポートされていないアスペクトをリストする [[sycl::device_has()]] C++ 属性
で修飾されている場合。
bool is_compatible(const std::vector<kernel_id>& kernelIds, const device& dev);
戻り値: kernelIds によって識別されるカーネルがデバイス dev と互換性がある場合は true を返します。
template<typename KernelName>bool is_compatible(const device& dev);
前提条件: テンプレート・パラメーター KernelName は、SYCL アプリケーションで定義されるカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名が存在せず、ラムダ関数として定義されたカーネルはこの関数を使用するため、カーネル
起動コマンドで KernelName を指定する必要があります。定義されていない KernelName に対してこの関数を呼び出すアプリケー
ションは不正な形式であり、実装は診断を行う必要があります。
is_compatible<State>({get_kernel_id<KernelName>()}, dev) と同等です。

4.11.10. カーネルバンドルに参加する
同じ状態の 2 つ以上のカーネルバンドルを 1 つの複合バンドルに結合できます。バンドルの結合は入力と同じ状態で新しいバンドルを生成するため、オンラインコンパイルやリンクと同一ではありません。結合することで、入力バンドルからすべてのデバイスイメージが結合され、同じデバイスイメージの重複するコピーが削除されてから、新しいバンドルが作成されます。
template<bundle_state State>kernel_bundle<State> join(const std::vector<kernel_bundle<State>>& bundles);286 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
戻り値: 重複が削除された入力 bundles 内のすべてのデバイスイメージのコピーを含む、新しいカーネルバンドルが返されます。新しいバンドルには、bundles と同じ関連コンテキストと関連デバイスのセットがあります。
スロー:• bundles 内のすべてのバンドルの関連コンテキストまたは関連デバイスのセットが同じでない場合、errc::invalid エラーコード
で例外をスローします。

4.11.11. オンラインコンパイルとリンク
実装がオンラインコンパイルまたはリンクを提供する場合、SYCL アプリケーションはこのセクションで定義されるフリー関数を使用して、カーネルバンドルを bundle_state::input から bundle_state::object バンドル状態に変換するか、bundle_state::object から
bundle_state::executable バンドル状態に変換します。
アプリケーションは、aspect::online_compiler または aspect::online_linker のデバイスを照会することで、実装がオンラインコンパ
イルまたはリンクを提供するか確認できます。
このセクションのすべての関数は property_list パラメーターを受け取ります。これは、コンパイルまたはリンクのセマンティクスに影響する可能性があります。コア SYCL 仕様では、現在このようなプロパティーは定義されませんが、ベンダーは拡張機能としてそのようなプロパティーを指定できます。
kernel_bundle<bundle_state::object>compile(const kernel_bundle<bundle_state::input>& inputBundle,
const std::vector<device>& devs,
const property_list& propList = {});
効果: inputBundle のデバイスイメージは、bundle_state::object 状態の 1 つ以上の新しいデバイスイメージに変換され、このデバイ
スイメージを含む新しいカーネルバンドルが作成されます。新しいバンドルは、devs のデバイスの少なくとも 1 つと互換性のある
inputBundles のカーネルを表現します。残りのカーネル (デバイス devs のどれとも互換性がない) はコンパイルされず、新しいカーネルバンドルには含まれません。
新しいバンドルは inputBundle と同じコンテキストが関連付けられており、新しいバンドルの関連するデバイスセットは devs (重複するデバイスが削除された状態) になります。
戻り値: 新しいカーネルのバンドルを返します。
スロー:• devs のデバイスのいずれかが inputBundle に関連付けられたデバイスのセットにない場合、または devs ベクトルが空である
場合、errc::invalid エラーコードの例外をスローします (kernel_bundle::get_devices() で定義)。

• オフラインコンパイルが失敗した場合、errc::build エラーコードで例外をスローします。
kernel_bundle<bundle_state::executable>link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,
const std::vector<device>& devs,
const property_list& propList = {});
効果: objectBundles の重複するデバイスイメージは、 join() によって結合されるように削除され、残りのデバイスイメージはbundle_state::executable 状態の 1 つ以上の新しいデバイスイメージに変換されて、新しいデバイスイメージを含む新しいカーネル
バンドルが作成されます。新しいバンドルは、devs のデバイスの少なくとも 1 つと互換性のある objectBundles のカーネルを表現します。残りのカーネル (devs のどのデバイスとも互換性がない) はリンクされず、新しいカーネルバンドルには含まれません。

第 4 章 SYCL プログラミング・インターフェイス | 287

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
新しいバンドルは objectBundles と同じコンテキストが関連付けられており、新しいバンドルの関連するデバイスセットは devs （重複したデバイスが削除された状態） になります。
戻り値: 新しいカーネルのバンドルを返します。
スロー:• objectBundles のすべてのバンドルが同じコンテキストに関連付けられていない場合、errc::invalid エラーコードで例外をス
ローします。

• devs のデバイスのいずれかが objectBundles に関連付けられたデバイスのセットにない場合、または devs ベクトルが空である場合、errc::invalid エラーコードの例外をスローします (kernel_bundle::get_devices() で定義)。

• オンラインリンクに失敗すると、errc::build エラーコードで例外をスローします。
kernel_bundle<bundle_state::executable>build(const kernel_bundle<bundle_state::input>& inputBundle,
const std::vector<device>& devs,
const property_list& propList = {});
効 果 : こ の 関 数 は オ ン ラ イ ン コ ン パ イ ル と リ ン ク の 両 方 を 行 い 、 bundle_state::input 状 態 の カ ー ネ ル バ ン ド ル をbundle_state::executable 状態のバンドルに変換します。inputBundle のデバイスイメージは、bundle_state::executable 状態の 1
つ以上の新しいデバイスイメージに変換され、このデバイスイメージを含む新しいカーネルバンドルが作成されます。新しいバンドル
は、devs のデバイスの少なくとも 1 つと互換性のある inputBundle のカーネルを表現します。残りのカーネル (devs のどのデバイスとも互換性ない) はコンパイルおよびリンクされず、新しいカーネルバンドルには含まれません。
新しいバンドルは inputBundle と同じコンテキストが関連付けられており、新しいバンドルの関連するデバイスセットは devs になります。
戻り値: 新しいカーネルのバンドル。
スロー:• devs のデバイスのいずれかが inputBundle に関連付けられたデバイスのセットにない場合、errc::invalid エラーコードの例外
をスローします (kernel_bundle::get_devices() で定義)。

• オフラインコンパイルまたはリンクが失敗した場合、errc::build エラーコードで例外をスローします。
kernel_bundle<bundle_state::object>// (1)

compile(const kernel_bundle<bundle_state::input>& inputBundle,
const property_list& propList = {});
kernel_bundle<bundle_state::executable>// (2)link(const kernel_bundle<bundle_state::object>& objectBundle,
const std::vector<device>& devs,
const property_list& propList = {});
kernel_bundle<bundle_state::executable>// (3)link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,
const property_list& propList = {});
kernel_bundle<bundle_state::executable>// (4)link(const kernel_bundle<bundle_state::object>& objectBundle,
const property_list& propList = {});

288 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
kernel_bundle<bundle_state::executable>// (5)

build(const kernel_bundle<bundle_state::input>& inputBundle,
const property_list& propList = {});
1.

compile(inputBundle, inputBundle.get_devices(), propList) と同等です。

2.

link({objectBundle}, devs, propList) と同等です。

3.

link(objectBundles, devs, propList) と同等です。devs は objectBundles 内のすべてのバンドルに共通の関連デバイスに関係
します。

4.

link({objectBundle}, objectBundle.get_devices(), propList) と同等です。

5.

build(inputBundle, inputBundle.get_devices(), propList) と同等です。

4.11.12. kernel_bundle クラス
kernel_bundle クラスの概要を以下に示します。さらに、このクラスが提供する共通特殊メンバー関数と共通メンバー関数については、
4.5.2 節の表 7 と表 8 を参照してください。
共通の参照セマンティクスを持つすべての SYCL オブジェクトと同様に、カーネルバンドルは等価に比較できます。同じバンドル状態の 2 つのバンドルは、同一コンテキストに関連付けられ、関連するデバイスセットが同じで、デバイスイメージのセットが同一である場
合、等しいと見なされます。
このクラスにはパブリック・デフォルト・コンストラクターがありません。
1.

namespace sycl {2.
3.

class kernel { /* ... */ };4.
5.

template<bundle_state State>

6.

class kernel_bundle {7.
8.

public:using device_image_iterator = __unspecified__ ;9.
10.

kernel_bundle() = delete;

11.
12.

bool empty() const noexcept;

13.
14.

backend get_backend() const noexcept;

15.
16.

context get_context() const noexcept;

17.
18.

std::vector<device> get_devices() const noexcept;

19.
20.

bool has_kernel(const kernel_id& kernelId) const noexcept;

21.
22.

bool has_kernel(const kernel_id& kernelId, const device& dev) const noexcept;

23.
24.

template<typename KernelName>

25.

bool has_kernel() const noexcept;

26.
27.

template<typename KernelName>

28.

bool has_kernel(const device& dev) const noexcept;

第 4 章 SYCL プログラミング・インターフェイス | 289

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
29.
30.

std::vector<kernel_id> get_kernel_ids() const;

31.
32.

/* 次のときにのみ利用可能: (State == bundle_state::executable) */33.

kernel get_kernel(const kernel_id& kernelId) const;

34.
35.

/* 次のときにのみ利用可能: (State == bundle_state::executable) */36.

template<typename KernelName>

37.

kernel get_kernel() const;

38.
39.

bool contains_specialization_constants() const noexcept;

40.
41.

bool native_specialization_constant() const noexcept;

42.
43.

template<auto& SpecName>

44.

bool has_specialization_constant() const noexcept;

45.
46.

/* 次のときにのみ利用可能: (State == bundle_state::input) */47.

template<auto& SpecName >48.

void set_specialization_constant(49.

typename std::remove_reference_t<decltype(SpecName)>::type value);

50.
51.

template<auto& SpecName >52.

typename std::remove_reference_t<decltype(SpecName)>::type53.

get_specialization_constant() const;

54.
55.

device_image_iterator begin() const;

56.
57.
58.

device_image_iterator end() const;
};

59.
60.

} // namespace sycl

4.11.12.1. 照会
次のメンバー関数はカーネルバンドルの各種クエリーを提供します。
bool empty() const noexcept;
戻り値: カーネルバンドルにデバイスイメージが含まれない場合にのみ true を返します。
backend get_backend() const noexcept;
戻り値: カーネルバンドルに関連付けられたバックエンドを返します。
context get_context() const noexcept;
戻り値: カーネルバンドルに関連付けられたコンテキストを返します。
std::vector<device> get_devices() const noexcept;
戻り値: カーネルバンドルに関連付けられたデバイスセットを返します。

290 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
bool has_kernel(const kernel_id& kernelId) const noexcept;// (1)

bool has_kernel(const kernel_id& kernelId, const device& dev) const noexcept;
1.

戻り値: カーネルバンドルに kernelId で識別されるカーネルが含まれる場合にのみ true を返します。

2.

戻り値: カーネルバンドルに kernelId で識別されるカーネルが含まれ、そのカーネルが dev と互換性がある場合にのみtrue を返します。

template<typename KernelName>bool has_kernel() const noexcept;// (1)

template<typename KernelName>bool has_kernel(const device& dev) const noexcept;// (2)

前提条件: テンプレート・パラメーター KernelName は、SYCL アプリケーションで定義されているカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名がないため、ラムダ関数として定義されたカーネルは、これらの関数を使用するため
カーネル呼び出しコマンドで KernelName を指定する必要があります。定義されていない KernelName に対してこれらの関数を呼び出すアプリケーションは、不正な形式であり実装は診断を発行する必要があります。
1.

戻り値: カーネルバンドルに KernelName で識別されるカーネルが含まれる場合にのみ true を返します。

2.

戻り値: カーネルバンドルに KernelName で定義されるカーネルが含まれ、そのカーネルがデバイス dev と互換性がある
場合にのみ true を返します。

std::vector<kernel_id> get_kernel_ids() const;
戻り値: カーネルバンドルに含まれるすべてのカーネル識別子のベクトルを返します。
kernel get_kernel(const kernel_id& kernelId) const;
前提条件: このメンバー関数は、カーネルのバンドル状態が bundle_state::executable である場合にのみ使用できます。
戻り値: バンドル内にある kernelId で識別されるカーネルを表す kernel オブジェクトを返します。
スロー:• カーネルバンドルに kernelId で識別されるカーネルが含まれない場合、errc::invalid エラーコードで例外をスローします。
template<typename KernelName>bool get_kernel() const;
前提条件: このメンバー関数は、カーネルバンドルの状態が bundle_state::executable の場合にのみ利用できます。テンプレート・パ
ラメーター KernelName は、SYCL アプリケーションで定義されているカーネルのタイプカーネル名である必要があります。ラムダ関数には標準のタイプ名がないため、ラムダ関数として定義されたカーネルは、これらの関数を使用するためカーネル呼び出しコマンド
で KernelName を指定する必要があります。定義されていない KernelName に対してこれらの関数を呼び出すアプリケーションは、
不正な形式であり実装は診断を発行する必要があります。
戻り値: バンドル内にある KernelName によって識別されるカーネルを表すカーネル・オブジェクトを返します。
スロー:• カーネルバンドルに KernelName で識別されるカーネルが含まれていない場合、errc::invalid エラーコードで例外をスローします。

第 4 章 SYCL プログラミング・インターフェイス | 291

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル

4.11.12.2. 特殊化定数のサポート
次のメンバー関数によって、アプリケーションはカーネルバンドルのデバイスイメージで使用される特殊化定数を操作できます。アプ
リケーションは、bundle_state::input 状態のカーネルバンドルに特殊化定数値を設定し、そのバンドルを bundle_state::object または bundle_state::executable にオンラインコンパイルできます。特殊化定数の値はコンパイルされたバンドルで決定され変更できません。バンドルがコンパイルされるまで値が設定されない特殊化定数は、デフォルト値が設定されます。

多くの実装では、SPIR-V などの bundle_state::input 状態のバンドルに中間言語表現が使用され、中間言語は特殊化定数をネイティブでサポートすることが期待されます。ただし、ネイティブサポートがない実装でも、別の方法で特殊化定数をサポートする必要があります。
bool contains_specialization_constants() const noexcept;
戻り値: カーネルバンドルに特殊化定数を使用するデバイスイメージが少なくとも 1 つ含まれる場合にのみ true を返します。
bool native_specialization_constant() const noexcept;
戻り値: カーネルバンドルで使用されるすべての特殊化定数が、バンドルのすべてのデバイスイメージでネイティブの特殊化定数である
場合にのみ true を返します。
template<auto& SpecName>bool has_specialization_constant() const noexcept;
戻り値: カーネルバンドル内のデバイスイメージが、アドレス SpecName である特殊化定数を使用する場合は true を返します。
template<auto& SpecName>
void set_specialization_constant(
typename std::remove_reference_t<decltype(SpecName)>::type value);
前提条件: このメンバー関数は、カーネルのバンドル状態が bundle_state::input である場合にのみ使用できます。
効果: このバンドルのアドレスが SpecName である特殊化定数の値を設定します。特殊化定数の値がそれ以前にバンドルで設定されている場合、値は上書きされます。
新しい値は、バンドル内のすべてのデバイスイメージに適用されます。バンドル内のデバイスイメージで特殊化定数が使用されていな
くても値を設定できます。これにより、バンドルからのカーネル実行には影響ありません。
template<auto& SpecName>
typename std::remove_reference_t<decltype(SpecName )>::typeget_specialization_constant() const;
戻り値: このカーネルバンドルのアドレスが SpecName である特殊化定数の値を設定します。次の値が返されます。

• 特殊化定数の値がそれ以前にバンドルで設定されている場合、その値が返されます。
• それ以外は、バンドルがほかのバンドルのコンパイル、リンクまたは結合によって生成され、特殊化定数がコンパイル、リンクおよび結合前にほかのバンドルで設定されている場合、その値が返されます。

• または、特殊化定数のデフォルト値が返されます。

4.11.12.3. デバイスイメージのサポート
次に示すメンバータイプと関数を使用すると、カーネルバンドルに含まれるデバイスイメージを反復できます。
using device_image_iterator =__unspecified__;292 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
LegacyForwardIterator の C++ 要件を満たすイテレーター・タイプ。イテレーターの参照タイプは、const device_image<State> であり、State は含まれる kernel_bundle と同じ状態です。
device_image_iterator begin() const;// (1)

device_image_iterator end() const;// (2)

1.

戻り値: カーネルバンドルに含まれる最初にデバイスイメージへのイテレーターを返します。

2.

戻り値: カーネルバンドルに含まれる最後のデバイスイメージの 1 つ先のイテレーターを返します。

4.11.13. kernel クラス
kernel クラスの概要を以下に示します。さらに、このクラスが提供する共通特殊メンバー関数と共通メンバー関数については、4.5.2
節の表 7 と表 8 を参照してください。
このクラスにはパブリック・デフォルト・コンストラクターがありません。
1.

namespace sycl {2.
3.

class kernel {4.

public:5.

kernel() = delete;

6.
7.

backend get_backend() const noexcept;

8.
9.

context get_context() const;

10.
11.

kernel_bundle<bundle_state::executable> get_kernel_bundle() const;

12.
13.

template <typename Param>

14.

typename Param::return_type get_info() const;

15.
16.

template <typename Param>

17.

typename Param::return_type get_info(const device& dev) const;

18.
19.

template <typename Param>

20.

typename Param::return_type get_backend_info() const;

21.

};

22.
23.

} // namespace sycl

4.11.13.1. 照会
次のメンバー関数はカーネルの各種クエリーを提供します。
backend get_backend() const noexcept;
戻り値: このカーネルに関連付けられたバックエンドを返します。
context get_context() const;
戻り値: このカーネルに関連付けられたコンテキストを返します。
kernel_bundle<bundle_state::executable> get_kernel_bundle() const;

第 4 章 SYCL プログラミング・インターフェイス | 293

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
戻り値: このカーネルを含むカーネルバンドルを返します。
template <typename Param>
typename Param::return_type get_info() const;
前提条件: param は表 136 で定義される info::kernel 記述子の 1 つでなければならず、タイプエイリアス param::return_type は表に従って定義されている必要があります。
戻り値: 呼び出されたデバイスに固有ではないカーネル情報を返します。
template <typename Param>
typename Param::return_type get_info(const device& dev) const;
前提条件: Param は表 137 で定義される info::kernel_device_specific 記述子の 1 つでなければならず、タイプエイリアス
Param::return_type は表に従って定義されている必要があります。
戻り値: カーネルが dev で呼び出されたときに適用されるカーネル情報を返します。
スロー:• カーネルがデバイス dev (is_compatible() で定義) と互換性がない場合、errc::invalid エラーコードで例外をスローします。
template <typename Param>
typename Param::return_type get_backend_info() const;
前提条件: Param は、SYCL バックエンド仕様で定義される記述子の 1 つでなければなりません。
戻り値: 呼び出されたデバイスに固有ではない、カーネルのバックエンド固有の情報を返します。
スロー:• Param に対応する SYCL バックエンドが、このカーネルバンドルに関連付けられる SYCL バックエンドと異なる場合、
errc::backend_mismatch エラーコードで例外をスローします。

4.11.13.2. カーネル情報記述子
get_info メンバー関数を使用して、info::kernel の info パラメーターを使用してカーネル情報を照会できます。すべてのコンテキスト
は、info パラメーターに対し有効な値を持つ必要があります。info::kernel のすべての info パラメーターは表 136 に示し、info::kernelの概要は A.5 節で説明します。
表 136.カーネルクラス情報記述子
カーネル記述子

戻り値

説明

info::kernel::num_args

uint32_t

この記述子は、バックエンド固有の相互運用関数を使用して構築されたカーネルバンドルに存在するカーネルを照会する、またはデバイスのビルトインカーネルを照会する場合にのみ意味を持ちます。この記述子のセマンティクスは、それぞれの SYCL
バックエンドの仕様で定義されます。
この記述子をほかのカーネルで使用すると、err::invalid エラー
コードで例外がスローされます。

info::kernel::attributes

std::string

294 | 第 4 章 SYCL プログラミング・インターフェイス

カーネル関数で指定された属性を返します (5.8 節で定義)。

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
get_info メンバー関数を使用して、info::kernel_device_specific の info パラメーターを指定して、カーネルにデバイス固有の情報 を 照 会 す る こ と も で き ま す 。 info::kernel_device_specific の す べ て の info パ ラ メ ー タ ー は 、 表 137 に 示 し ま す 。
info::kernel_device_specific の概要は A.5 節で説明します。
表 137.デバイス固有のカーネル情報記述子
デバイス固有のカーネル情報記述子

戻り値

説明

info::kernel_device_specific::grange<3>

この記述子は、デバイスタイプが device_type::custom である

lobal_work_size

場合、またはカーネルがビルトインカーネルである場合にのみ使用できます。この記述子のセマンティクスは、それぞれの
SYCL バックエンドの仕様で定義されますが、目的はカーネルの最大グローバル work-item サイズを返すことです。
この記述子をほかのカーネルで使用すると、err::invalid エラー
コードで例外がスローされます。

info::kernel_device_specific::w

size_tork_group_size
info::kernel_device_specific::cgroup の最大 work-item 数を返します。
range<3>

ompile_work_group_size
info::kernel_device_specific::p

特定のデバイスでカーネルを実行する際に使用できる work-

適用可能であれば、デバイス・コンパイラーで指定された workgroup サイズを返します。それ以外は {0,0,0} を返します。

size_treferred_work_group_size_multip le

特定のデバイスでカーネルを実行する際に適切である workgroup サイズの倍数値を返します。これはパフォーマンスに対す るヒ ント とし て使用さ れます 。 この 値は、
info::kernel_device_specific::work_group_size で返される値以下でなければなりません。

info::kernel_device_specific::psize_trivate_mem_size

カーネル内の work-item で使用されるプライベート・メモリーの最小量をバイト単位で返します。この値には、カーネルを実行する実装に必要なプライベート・メモリーが含まれることがあり、これにはビルトイン言語で使用されるメモリーやカーネル内のプライベート・アドレス空間で宣言される変数が含まれます。

info::kernel_device_specific::max_num_sub_groups

uint32_t

このカーネルの sub-group の最大数を返します。

uint32_t

カーネルで指定される sub-group 数、または 0 (未定義の場合)

info::kernel_device_specific::cを返します。

ompile_num_sub_groups
uint32_t

このカーネルの最大 sub-group サイズを返します。

uint32_t

カーネルで指定される必須 sub-group 数、または 0 (未定義のinfo::kernel_device_specific::max_sub_group_size

info::kernel_device_specific::c場合) を返します。

ompile_sub_group_size

第 4 章 SYCL プログラミング・インターフェイス | 295

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル

4.11.14. device_image クラス
device_image クラスの概要を以下に示します。さらに、このクラスが提供する共通特殊メンバー関数と共通メンバー関数については、
4.5.2 節の表 7 と表 8 を参照してください。
1.

namespace sycl {2.
3.

template<bundle_state State>

4.

class device_image {5.

public:6.

device_image() = delete;7.
8.

bool has_kernel(const kernel_id& kernelId) const noexcept;

9.
10.
11.

bool has_kernel(const kernel_id& kernelId, const device& dev) const noexcept;
};

12.
13.

} // namespace sycl

このクラスにはパブリック・コンストラクターがありません。
bool has_kernel(const kernel_id& kernelId) const noexcept;// (1)

bool has_kernel(const kernel_id& kernelId, const device& dev) const noexcept;// (2)

1.

戻り値: デバイスイメージに kernelId で識別されるカーネルが含まれる場合にのみ true を返します。

2.

戻り値: デバイスイメージに kernelId で識別されるカーネルが含まれ、そのカーネルが dev と互換性がある場合にのみtrue を返します。

4.11.15. 使用例
このセクションでは、カーネルバンドルの一般的な使い方を示すいくつかの例を説明します。これらの例は、カーネルバンドルのインターフェイスの定義を明確にするためのものですが、この節の内容は説明を目的としています。

4.11.15.1. オンラインコンパイルのタイミングを制御
アプリケーションがカーネルをデバイスに送信する前に、再コンパイルが必要となる場合があります。これにより、デフォルト動作に縛られることなく、オンラインコンパイルのオーバーヘッドが発生するタイミングをアプリケーションが制御できるようになります (カーネルがデバイスに送信されたときに、オンラインコンパイルが行われる可能性があります)。次の例では、これを行う方法を説明します。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

3.
4.

int main() {5.

queue myQueue;

6.

auto myContext = myQueue.get_context();

7.
8.

// この get_kernel_bundle() を呼び出すことで、事前コンパイルによってデバイス用に

9.

// カーネルがコンパイル済みでない限り、"myContext" 内のデバイスで実行される

10.

// アプリケーション・カーネルのオンラインコンパイルを強制します11.

auto myBundle = get_kernel_bundle<bundle_state::executable>(myContext);

12.

296 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
13.

myQueue.submit([&](handler& cgh) {14.

// use_kernel_bundle() を呼び出すと、次の parallel_for() は、

15.

// "myBundle" から事前コンパイルされたカーネルを使用します

16.

cgh.use_kernel_bundle(myBundle);

17.
18.

cgh.parallel_for(range{1024}, ([=](item index) {19.

// カーネルコード

20.

}));

21.

});

22.
23.
24.

myQueue.wait();}4.11.15.2. 特殊化定数
アプリケーションはデバイスに送信される前に、カーネルバンドルを使用してカーネルの特殊化定数の値を設定できます。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (optional) avoids need for "sycl::" before SYCL names

3.
4.

// Forward declare names for our two kernels.

5.

class MyKernel1;

6.

class MyKernel2;

7.
8.

extern int get_width();9.

extern int get_height();

10.
11.

// Declare specialization constants used in our kernels.

12.

constexpr specialization_id<int> width;13.

constexpr specialization_id<int> height;

14.
15.

int main() {16.

queue myQueue;

17.

auto myContext = myQueue.get_context();

18.
19.

// Get the identifiers for our kernels, then get an input kernel bundle that20.

// contains our two kernels.

21.

auto kernelIds = {get_kernel_id<MyKernel1>(), get_kernel_id<MyKernel2>()};

22.

auto inputBundle = get_kernel_bundle<bundle_state::input>(myContext, kernelIds);

23.
24.

// Set the values of the specialization constants.

25.

inputBundle.set_specialization_constant<width>(get_width());

26.

inputBundle.set_specialization_constant<height>(get_height());

27.
28.

// Build the kernel bundle into an executable form. The values of the29.

// specialization constants are compiled in.

30.

auto exeBundle = build(inputBundle);

31.
32.

myQueue.submit([&](handler& cgh) {33.

// Use the kernel bundle we built in this command group.

34.

cgh.use_kernel_bundle(exeBundle);

35.

cgh.parallel_for<MyKernel1>(range{1024}, ([=](item index, kernel_handler kh) {第 4 章 SYCL プログラミング・インターフェイス | 297

SYCL 2020 リビジョン 6 - 4.11 カーネルバンドル
36.

// Read the value of the specialization constant.

37.

int w = kh.get_specialization_constant<width>();38.

// ...

39.

}));

40.

});

41.
42.

myQueue.submit([&](handler& cgh) {43.

// This command group uses the same kernel bundle.

44.

cgh.use_kernel_bundle(exeBundle);

45.

cgh.parallel_for<MyKernel2>(range{1024}, ([=](item index, kernel_handler kh) {46.

int h = kh.get_specialization_constant<height>();47.

// ...

48.

}));

49.

});

50.
51.
52.

myQueue.wait();}4.11.15.3. カーネルの内容調査
アプリケーションは、カーネルバンドルを使用してカーネルの内容を調査し、その情報によって呼び出し時の引数を調整します。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

3.
4.

class MyKernel; // カーネル名を前方宣言します5.
6.

int main() {7.

size_t N = 1024;

8.

queue myQueue;

9.

auto myContext = myQueue.get_context();

10.

auto myDev = myQueue.get_device();

11.
12.

// カーネルを含む実行可能なカーネルバンドルを取得します

13.

kernel_id kernelId = get_kernel_id<MyKernel>();14.

auto myBundle = get_kernel_bundle<bundle_state::executable>(myContext, {kernelId});

15.
16.

// デバイスで実行する際にカーネルの最大 work-group サイズを取得します

17.

kernel myKernel = myBundle.get_kernel(kernelId);

18.

size_t maxWgSize = myKernel.get_info<info::kernel_device_specific::work_group_size>( myDev);

19.
20.

// 最大 work-group サイズに基づいて、カーネルの反復に使用する

21.

// 適切な ND-range を計算します22.

std::array<size_t, 11> divisors = {1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1};

23.

size_t wgSize = *std::find_if(divisors.begin(), divisors.end(), [=](auto d) {24.

return (d <= maxWgSize);

25.

});

26.

nd_range myRange {range{N}, range{wgSize}};

27.
28.

myQueue.submit([&](handler& cgh) {29.

// 照会したカーネルバンドルを使用して、work-group サイズが30.

// 実行するカーネルと一致することを確認します

298 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.12 カーネルの定義
31.

cgh.use_kernel_bundle(myBundle);

32.

cgh.parallel_for<MyKernel>(myRange, ([=](nd_item<1> index) {33.

// カーネルコード

34.

}));

35.

});

36.
37.
38.

myQueue.wait();}4.11.15.4. デバイス・ビルトイン・カーネルの呼び出し
アプリケーションは、カーネルバンドルを使用してデバイス・ビルトイン・カーネルを呼び出します。
1.

#include <sycl/sycl.hpp>

2.

using namespace sycl; // (オプション) SYCL 名の前に "sycl::"は必要ありません

3.
4.

int main() {5.

queue myQueue;

6.

auto myContext = myQueue.get_context();

7.

auto myDevice = myQueue.get_device();8.
9.

const std::vector<kernel_id> builtinKernelIds =10.

myDevice.get_info<info::device::built_in_kernel_ids>();

11.
12.

// デバイスでサポートされるすべてのビルトインカーネルを含む

13.

// 実行可能 kernel_bundle を取得します

14.

kernel_bundle<bundle_state::executable> myBundle =15.

get_kernel_bundle(myContext, {myDevice}, builtinKernelIds);

16.
17.

// ビルトインカーネルに関連する詳細情報を照会したり、コマンドグループに送信するために

18.

// 使用するカーネル・オブジェクトを取得します ここでは、

19.

// デバイスが少なくとも 1 つのビルトインカーネルをサポートすることを前提とします20.

kernel builtinKernel = myBundle.get_kernel(builtinKernelIds[0]);

21.
22.

// ビルトインカーネルを送信

23.

myQueue.submit([&](handler& cgh) {24.

// 引数の設定は、バックエンドと使用されるカーネルによって異なります25.

cgh.set_args(...);

26.

cgh.parallel_for(range{1024}, builtinKernel);

27.

});

28.
29.
30.

myQueue.wait();}4.12. カーネルの定義
SYCL では、SYCL デバイスで実行される関数は、SYCL カーネル関数と呼ばれます。SYCL カーネル関数を含むカーネルは、特定のデバイスで実行するためデバイスキューに送信されます。
SYCL カーネル関数の戻り値タイプは void であり、ホストとデバイス間のすべてのメモリーアクセスはアクセサーまたは USM ポイン
ターを介して行われます。

第 4 章 SYCL プログラミング・インターフェイス | 299

SYCL 2020 リビジョン 6 - 4.12 カーネルの定義
カーネルは、名前付き関数オブジェクトまたはラムダ関数として定義します。バックエンドは、カーネルを定義する相互運用インターフェイスを提供する場合もあります。

4.12.1. 名前付き関数オブジェクトとしてカーネルを定義
カーネルは名前付き関数オブジェクト・タイプとして定義することができます。関数オブジェクトは、C++ 関数オブジェクトと同じ機能を提供しますが、デバイス間でのコピーを可能にするため SYCL の使用条件に従う必要があります。カーネル関数は、カーネル関数オ
ブジェクト・タイプをテンプレート化することでテンプレートにできます。カーネル命名の制限に関する詳細は 5.2 節を参照してください。
operator() メンバー関数は const 修飾される必要があり、特定のカーネルで定義されるデータアクセスに応じて異なるパラメーターを受け取ります。operator() 関数がメンバー変数に書き込みを行うと動作は未定義となります。
次の例は、SYCL カーネル関数 RandomFiller を定義します。これはバッファーを乱数で初期化します。
乱数は、コマンドグループの処理中に関数オブジェクトの構築で生成されます。関数オブジェクトの operator() メンバー関数は、item
オブジェクトを受け取ります。このメンバー関数は、実行レンジの work-item ごとに呼び出され、乱数値はバッファーの各要素に割り当てられます。この例では、アクセサーとスカラー乱数は、関数オブジェクトのメンバーであるため、デバイスカーネルへの引数となります。引数をカーネルに渡す通常の規則が適用されます。
1.

class RandomFiller {2.

public:3.

RandomFiller(accessor<int> ptr)

4.

: ptr_ { ptr } {5.

std::random_device hwRand;6.

std::uniform_int_distribution<> r { 1, 100 };7.

randomNum_ = r(hwRand);

8.

}

9.

void operator()(item<1> item) const { ptr_[item.get_id()] = get_random(); }10.

int get_random() { return randomNum_; }

11.
12.

private:13.

accessor<int> ptr_;

14.

int randomNum_;

15.

};

16.
17.

void workFunction(buffer<int, 1>& b, queue& q, const range<1> r) {18.

myQueue.submit([&](handler& cgh) {19.

accessor ptr { buf, cgh };20.

RandomFiller filler { ptr };

21.
22.

cgh.parallel_for(r, filler);

23.
24.

});
}

4.12.2. ラムダ関数としてカーネルを定義
C++ では、関数オブジェクトはラムダ関数を使用して定義できます。SYCL では、カーネルはラムダ関数として定義できます。SYCL のラムダ関数名はオプションで指定できます (呼び出し元のメンバー関数にテンプレート・パラメーターとして指定)。その場合、ラムダ名
は C++ のタイプ名であり、名前空間スコープで前方宣言可能である必要があります。ラムダ関数がテンプレート引数に依存する場合、300 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.12 カーネルの定義
ラムダ関数名 (指定されていれば) には名前空間スコープで前方宣言可能であるテンプレート引数が含まれている必要があります。ラムダ関数の名前に使用されるクラスは、命名にのみ使用され定義の必要はありません。カーネル命名の制限に関する詳細は 5.2 節を参照してください。
ラムダ関数のカーネル関数はラムダ関数そのものです。カーネルラムダは、すべてをキャプチャー・コピー (つまり. [=] を使用) する必要があり、可変指定子を使用してはなりません。
1.

// 明示的なカーネル名は、オプションで名前空間スコープを前方宣言できます2.

class MyKernel;

3.
4.

myQueue.submit([&](handler& h) {5.
6.

// 以前に前方宣言されたタイプでカーネルを明示的に命名します7.

h.single_task<MyKernel>([=]{

8.

// [カーネルコード]

9.

});

10.
11.

// 名前空間スコープでタイプを前方宣言せずにカーネルに

12.

// 明示的に名前を付けます 名前空間スコープで宣言されていない場合でも、

13.

// 名前空間スコープで前方宣言可能でなければなりません

14.

h.single_task<class MyOtherKernel>([=]{

15.

// [カーネルコード]

16.
17.

});
});

明示的なラムダの命名方法を次のコードに示します。ここでは、前方宣言できないカーネル名 (std::complex) 内のクラスを使用する不正な例が含まれます。
1.

// 明示的なカーネル名は、オプションで名前空間スコープで前方宣言できます2.

class MyForwardDeclName;

3.
4.

template <typename T>

5.

class MyTemplatedKernelName;

6.
7.

// テンプレート化されたカーネルを定義して起動します8.

template <typename T>

9.

void templatedFunction() {10.

queue myQueue;

11.
12.

// A を起動: 明示的なカーネル名なし

13.

myQueue.submit([&](handler& h) {14.

h.single_task([=]{

15.

// [T タイプに依存するカーネルコード]

16.
17.

});
});

18.
19.

// B を起動: 呼び出し時にカーネル名を付けます (これはオプションです)20.

myQueue.submit([&](handler& h) {21.

h.single_task<MyTemplatedKernelName<T>>([=]{

22.

// 提供されるカーネル名 (MyTemplatedKernelName<T>) は、

23.

// カーネルが存在するため T に依存します T は、名前空間スコープで24.

// 前方宣言可能である必要があります25.

第 4 章 SYCL プログラミング・インターフェイス | 301

SYCL 2020 リビジョン 6 - 4.12 カーネルの定義
26.

// [T タイプに依存するカーネルコード]

27.

});

28.
29.

});
}

30.
31.

int main() {32.

queue myQueue;

33.
34.

myQueue.submit([&](handler& h) {35.

// このカーネル呼び出し内で MyKernel を宣言します これは、名前空間スコープでの36.

// 前方宣言はオプションであるため許可されます37.

h.single_task<class MyKernel>([=]{

38.

// [カーネルコード]

39.

});

40.

});

41.
42.

myQueue.submit([&](handler& h) {43.

// 名前空間スコープで前方宣言されたカーネル名を使用します

44.

h.single_task<MyForwardDeclName>([=]{

45.

// [カーネルコード]

46.

});

47.

});

48.
49.

templatedFunction<int>(); // OK

50.
51.

templatedFunction<std::complex<float>>();

52.

// std::complex は C++ に従って前方宣言可能ではなく、前方宣言可能が

53.
54.

// 明示的なカーネル名であるため、A の呼び出しは許可されますが、B は許可されません}

4.12.3. is_device_copyable タイプ特性
namespace sycl {template<typename T>
struct is_device_copyable;
template<typename T>
inline constexpr bool is_device_copyable_v = is_device_copyable<T>::value;};
is_device_copyable は、タイプ T がデバイスコピー可能であることを示すユーザー固有のクラス・テンプレートです。

• is_device_copyable は、Cpp17UnaryTrait の要件を満たす必要があります。
• is_device_copyable がデバイスコピー可能なタイプのすべての要件を満たさない T で is_device_copyable_v<T> == true となるように特殊化されていると、結果は未定義となります。
アプリケーションがデバイスコピー可能なタイプ (3.13.1 節で定義) の要件を満たすタイプ UDT を定義していても、タイプがそのセクションで暗黙的にデバイスコピー可能であると定義されていない場合、アプリケーションはデバイスコピー可能なタイプを必要とする
コンテキストで使用するため std:true_type から派生する is_device_copyable の特殊化を提供しなければなりません。そのような特殊化は次のように宣言します。

302 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.12 カーネルの定義
template<>struct sycl::is_device_copyable<UDT> : std::true_type {};実装が SYCL_DEVICE_COPYABLE を 1 に定義していなくてもこの特殊化を提供することは許容されますが、タイプはデバイスでコピー可能なタイプとして利用できず、特殊化は無視されます。

4.12.4. カーネルへパラメーターを渡す規則
SYCL アプリケーションは、カーネルが名前付き関数オブジェクトであるか、ラムダ関数であるかに応じてさまざまな方法でカーネルにパラメーターを渡します。カーネルが名前付きオブジェクトである場合、operator() メンバー関数 (またはカーネルが呼び出す他のメンバー関数) は、同じ名前付きの関数オブジェクト内のメンバー関数を参照できます。このようなメンバー関数はすべて、カーネルのパラメーターになります。カーネルがラムダ関数である場合、ラムダ関数でキャプチャーされた変数は、すべてカーネルのパラメーターになります。
パラメーターの受け渡し方法に関わりなく、次の規則がカーネル・パラメーターとして許可されるタイプを定義します。

• デバイスコピー可能なタイプは、すべて有効なパラメーター・タイプです。
• 次の SYCL タイプは有効なパラメーター・タイプです。
◦ target::device でテンプレート化された accessor◦ 非 推 奨 の パラ メ ー タ ーで テン プ レ ート 化 さ れ た accessor: target::global_buffer 、 target::­constant_buffer 、 ま たは
target::local◦ local_accessor◦ image_target::device でテンプレート化された unsampled_image_accessor◦ image_target::device でテンプレート化された sampled_image_accessor◦ stream◦ id◦ range◦ T がデバイスコピー可能な場合、marray＜T, NumElements>◦ vec<T, NumElements>• T が有効なパラメーター・タイプである場合、要素タイプ T の配列も有効なパラメーター・タイプです。
• タイプ T の非静的メンバー変数を持つクラスタイプ S は、T が有効なパラメーター・タイプで、S がこのメンバー関数以外の有効なパラメーター・タイプである場合に有効なパラメーター・タイプとなります。

• タイプ T の非仮想基本クラスを持つクラスタイプ S は、T が有効なパラメーター・タイプで、S がこの基本クラス以外の有効なパラメーター・タイプである場合に有効なパラメーター・タイプとなります。

ポインタータイプは容易にコピー可能であるため、カーネルにパラメーターとして渡すことができますが、ポイン
ター値のみがカーネルに渡されます。カーネルでポインターを逆参照すると、ポインターがデバイスでアクセス可能な USM メモリー領域内のアドレスを指していない限り、未定義の動作となります。
参照タイプは容易にコピーできないため、カーネルにパラメーターとして渡されない場合があります。

第 4 章 SYCL プログラミング・インターフェイス | 303

SYCL 2020 リビジョン 6 - 4.13 エラー処理

reducer クラスは、異なる方法でカーネルに渡される特殊タイプのカーネル・パラメーターです。4.9.2 節では、このパラメーター・タイプの用法について説明しています。

4.13. エラー処理
4.13.1. エラー処理規則
SYCL アプリケーション (ホストコード) のエラー処理には C++ 例外を使用します。エラーが発生すると API 関数呼び出しによってスローされ、標準 C++ の例外処理メカニズムを介してユーザーにキャッチされる可能性があります。
SYCL アプリケーションは、ホストとデバイスコードの実行が特定のポイントを除いて分離されているという意味では非同期です。例えば、SYCL タスクグラフの依存関係が満たされたときにデバイスコードの実行が開始されることがあります。これは、ホストコードの実行とは非同期に行われます。これによりデバイスで発生するエラーは、ホスト API 呼び出しから直接スローすることができません。これは、デバイスのアクションをエンキューする呼び出しは、通常、エラーが発生するときにはリターンされているためです。このようなエラーは非同期エラーと呼ばれ、エラーの原因となるタスクが実行されるまでは検出されません。

4.13.1.1. 非同期例外ハンドラー
キュークラスとコンテキスト・クラスは、オプションとして構築時に非同期ハンドラー・オブジェクト async_handler を受け取ることができ、パラメーターとして exception_list により関数クラスやラムダ関数を呼び出すことができます。async_handler の呼び出しは、
キ ュ ー メ ン バ ー 関 数 queue::wait_and_throw() ま た は queue::throw_asynchronous() に よ っ て 、 イ ベ ン ト メ ン バ ー 関 数
event::wait_and_throw() または未処理の非同期エラーを含むキューやコンテキストの破棄時に自動的にトリガーされることがあります。呼び出されると、async_handler が起動され、キューまたはコンテキストに関連付けられた未処理の非同期エラーを表す例外オ
ブジェクトのリストを含む exception_list 引数を受け取ります。
非同期エラーのインスタンスが async_handler に渡されるとエラーのインスタンスは処理のため使用され、以降の async_handler
呼び出しでは報告されません。
async_handler は、名前付き関数オブジェクト、ラムダ関数、または std::function である場合もあります。
async_handler に渡される exception_list オブジェクトは、SYCL ランタイムで構築されます。

4.13.1.2. async_handler なしの動作
ユーザー定義の非同期エラー・ハンドラー・オブジェクト async_handler がないキューまたはコンテキストで非同期エラーが発生すると、4.13.1.1 節で説明するように実装定義のデフォルトの async_handler が呼び出され、ユーザー定義の async_handler と同じ状況
でエラー処理されます。デフォルトの async_handler は、可能であれば渡されたすべてのエラーを何らかの方法で報告する必要があり、
std::terminate または同等の呼び出しを行わなければなりません。

4.13.1.3. async_handler の優先順位
SYCL ランタイムが非同期エラーを特定のキューに関連付けできる場合、次のようになります。

• キューが async_handler で構築されると、そのハンドラーが呼び出されてエラー処理が行われます。
• それ以外で、キューで囲まれたコンテキストが async_handler で構築されていれば、そのハンドラーが呼び出されてエラー処理が行われます。

304 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.13 エラー処理• さらに、構築時にキューまたはコンテキストのいずれにもハンドラーが渡されなかった場合、4.13.1.2 節で説明するようにエラーを処理するデフォルトハンドラーが呼び出されます。

• このリストのすべてのハンドラー呼び出しは、4.13.1.1 節で定義されるタイミングで発生します。
SYCL ランタイムが非同期エラーを特定のキューに関連付けできない場合、次のようになります。

• エラー発生が発生したコンテキストが async_handler で構築されていれば、そのハンドラーが呼び出されてエラー処理が行われます。

• それ以外は、構築時に関連コンテキストのいずれにもハンドラーが渡されなかった場合、4.13.1.2 節で説明するように、エラーを処理するデフォルトハンドラーが呼び出されます。

• このリストのすべてのハンドラー呼び出しは、4.13.1.1 節で定義されるタイミングで発生します。

4.13.1.4. セカンダリー・キューでの非同期エラー
セカンダリー・キューが指定されるコマンドグループを実行、またはキューに投入する際に非同期エラーが発生すると、コマンドグルー
プはプライマリー・キューではなくセカンダリー・キューに投入される可能性があります。この場合のエラー処理も両方のキューで提供される async_handler によって構成されます。どのキューにも async_handler が指定されていない場合、非同期エラー処理はキューに関連付けられたコンテキストを介して行われ、それらも async_handler なしで構成されている場合、デフォルトハンドラーが使用されます。プライマリー・キューに障害が発生し、そのキューの構築時に exception_list パラメーターを持つ async_handler が指定されている場合、エラーが追加されてユーザーが例外処理を選択するたびにスローされる可能性があります。プライマリー・キューでエラーが発生し、セカンダリー・キューが指定されることでカーネルの実行がセカンダリー・キューに再スケジュールされると、カーネル実行のエラーレポートは前述のように同じ方法でセカンダリー・キューを介して実行されます。セカンダリー・キューでもエラーが発生する可能性があり、async_handler が指定されそのキューで wait_and_throw() または throw() が呼び出されるとエラーがスローされます。
async_handler が 指 定 さ れ な い 場 合 、 キ ュ ー の コ ン テ キ ス ト に 関 連 付 け ら れ た ハ ン ド ラ ー が 使 用 さ れ 、 コ ン テ キ ス ト に もasync_handler がない場合は、デフォルトのハンドラーが使用されます。その関数によって返されるコマンドグループ関数オブジェク
トのイベントは、カーネルがエンキューされたキューに関連付けられます。
以下は、SYCL 例外をキャッチしてエラーメッセージを出力する例です。
1.

void catch_any_errors(sycl::context const& ctx) {

2.

try {

3.

do_something_to_invoke_error(ctx);

4.

}

5.

catch(sycl::exception const& e) {6.

std::cerr << e.what();

7.
8.

}
}

以下は、errc::invalid エラーコードで SYCL 例外をキャッチして、エラーメッセージを出力する例です。
1.
2.

void catch_invalid_errors(sycl::context const& ctx) {
try {

3.

do_something_to_invoke_error(ctx);

4.

}

5.

catch(sycl::exception const& e) {6.

if(e.code() == sycl::errc::invalid) {7.

std::cerr << "Invalid error: " << e.what();

8.

}

9.

else {

10.
11.

throw;}

第 4 章 SYCL プログラミング・インターフェイス | 305

SYCL 2020 リビジョン 6 - 4.13 エラー処理
12.
13.

}
}

以下の例は、SYCL 例外をキャッチしてカテゴリーを調査することで SYCL バックエンドをチェックし、カテゴリーが OpenCL SYCL バッ
クエンドである場合は OpenCL SYCL バックエンドのエラーコードを処理し、それ以外は標準エラーコードをチェックします。
1.

void catch_backend_errors(sycl::context const& ctx) {

2.

try {

3.

do_something_to_invoke_error(ctx);

4.

}

5.

catch(sycl::exception const& e) {6.

if(e.category() == sycl::error_category_for<sycl::backend::opencl>()) {7.

switch(e.code().value()) {8.

case CL_INVALID_PROGRAM:

9.

std::cerr << "OpenCL invalid program error: " << e.what();

10.

/* ...*/

11.

}

12.

else {

13.

throw;

14.

}

15.

}

16.

else {

17.

if(e.code() == sycl::errc::invalid) {18.

std::cerr << "Invalid error: " << e.what();

19.

}

20.

else {

21.

throw;

22.

}

23.

}

24.
25.

}
}

4.13.2. 例外クラス・インターフェイス
1.

namespace sycl {2.
3.

using async_handler = std::function<void(sycl::exception_list)>;

4.
5.
6.

class exception : public virtual std::exception {public:7.

exception(std::error_code ec, const std::string& what_arg);

8.

exception(std::error_code ec, const char* what_arg);

9.

exception(std::error_code ec);

10.

exception(int ev, const std::error_category& ecat, const std::string& what_arg);

11.

exception(int ev, const std::error_category& ecat, const char* what_arg);

12.

exception(int ev, const std::error_category& ecat);

13.
14.

exception(context ctx, std::error_code ec, const std::string& what_arg);

15.

exception(context ctx, std::error_code ec, const char* what_arg);

16.

exception(context ctx, std::error_code ec);

17.

exception(context ctx, int ev, const std::error_category& ecat, const std::string& what_arg);

18.

exception(context ctx, int ev, const std::error_category& ecat, const char* what_arg);

306 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.13 エラー処理
19.

exception(context ctx, int ev, const std::error_category& ecat);

20.
21.

const std::error_code& code() const noexcept;

22.

const std::error_category& category() const noexcept;

23.
24.

const char* what() const;

25.
26.

bool has_context() const noexcept;

27.
28.

context get_context() const;
};

29.
30.

class exception_list {31.

// 非同期例外のリストのコンテナーとして使用

32.

public:33.

using value_type = std::exception_ptr;

34.

using reference = value_type&;

35.

using const_reference = const value_type&;

36.

using size_type = std::size_t;

37.

using iterator = /* 未定義 */;38.

using const_iterator = /* 未定義 */;

39.
40.

size_type size() const;

41.

iterator begin() const; // 最初の非同期例外

42.

iterator end() const; // 以前の最後の非同期例外を参照

43.

};

44.
45.

enum class errc : /* 未定義 */{46.

success = 0,47.

runtime,48.

kernel,49.

accessor,50.

nd_range,

51.

event,

52.

kernel_argument,

53.

build,

54.

invalid,55.

memory_allocation,

56.

platform,

57.

profiling,

58.

feature_not_supported,59.

kernel_not_supported,

60.

backend_mismatch

61.

};

62.
63.

template<backend b>

64.

using errc_for = typename backend_traits<b>::errc;

65.
66.

std::error_code make_error_code(errc e) noexcept;

67.
68.

const std::error_category& sycl_category() noexcept;

69.
70.

template<backend b>

第 4 章 SYCL プログラミング・インターフェイス | 307

SYCL 2020 リビジョン 6 - 4.13 エラー処理
71.

const std::error_category& error_category_for() noexcept;

72.
73.

} // namespace sycl

74.
75.

namespace std {

76.
77.

template <>78.

struct is_error_code_enum</* see-below */> : true_type

{};

79.
80.

} // namespace std

同期および非同期の例外リストを提供するため、SYCL exception_list クラスを利用できます。
エラーは、SYCL ライブラリーと SYCL ホストの両方で発生することも、SYCL バックエンドから直接発生することもあります。これらの例外のメンバー関数は、対応する情報を提供します。SYCL バックエンドは、sycl::exception オブジェクト、またはその派生クラスのいずれかから派生する限り、追加の例外クラス・オブジェクトを提供できます。
std::true_type から継承される sycl::errc では、std::is_error_condition_enum の特殊化を定義する必要があります。
std::is_error_code_enum の 特 殊 化 は 、 各

Backend の

std::true_type か ら 継 承 す る

sycl::errc お よ びbackend_traits<Backend>::errc に対して定義が必要です。ここで、backend は enum クラス backend の列挙型です。
表 138. SYCL exceptionクラスのメンバー関数
メンバー関数説明

exception(std::error_code ec, const std::string& what_arg)

exception を作成。what() で返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(std::error_code ec, const char* what_arg)

exception を作成。what() で返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(std::error_code ec)

exception を作成。

exception(int ev, const std::error_category& ecat, const

エラーコード ev とベースとなるエラーカテゴリー ecat を使用し

std::string& what_arg)て例外を構築します。what() で返される文字列には、部分文字列
として what_arg が含まれることが保証されます。

exception(int ev, const std::error_category& ecat, const
char* what_arg)

エラーコード ev とベースとなるエラーカテゴリー ecat を使用して例外を構築します。what() で返される文字列には、部分文字列
として what_arg が含まれることが保証されます。

exception(int ev, const std::error_category& ecat)

エラーコード ev とベースとなるエラーカテゴリー ecat を使用して例外を構築します。

exception(context ctx, std::error_code ec, const std

関連する SYCL コンテキスト ctx で例外を構築します。what() で::string& what_arg)

返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(context ctx, std::error_code ec, const char*

関連する SYCL コンテキスト ctx で例外を構築します。what() で

what_arg)

返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(context ctx, std::error_code ec)

308 | 第 4 章 SYCL プログラミング・インターフェイス

関連する SYCL コンテキスト ctx で例外を構築します。

SYCL 2020 リビジョン 6 - 4.13 エラー処理

メンバー関数説明

exception(context ctx, int ev, const std::error_category&

関連する SYCL コンテキスト ctx、エラーコード ev、およびベース

ecat, const std::string& what_arg)となるエラーカテゴリー ecat で例外を構築します。what() で返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(context ctx, int ev, const std::error_category&

関連する SYCL コンテキスト ctx、エラーコード ev、およびベース

ecat, const char* what_arg)となるエラーカテゴリー ecat で例外を構築します。what() で返される文字列には、部分文字列として what_arg が含まれることが保証されます。

exception(context ctx, int ev, const std::error_category&

関連する SYCL コンテキスト ctx、エラーコード ev、およびベース

ecat)となるエラーカテゴリー ecat で例外を構築します。

const std::error_code& code() const noexcept

例外内部でストアされているエラーコードを返します。

const std::error_category& category() const noexcept

例外内部でストアされているエラーコードのカテゴリーを返します。

const char* what() const

例外をトリガーしたエラーを示す、実装で定義される null 以外の定数 C 形式の文字列を返します。

bool has_context() const noexcept

この SYCL 例外に SYCL context が関連付けられる場合は true
を返し、それ以外は false を返します。

context get_context() const

SYCL 例外に関連付けられている SYCL context を返します。この SYCL 例外に SYCL context がない場合、errc::invalid エラー
コードで例外をスローする必要があります。

表 139. exception_list のメンバー関数
メンバー関数説明

size_t size() const

リストのサイズを返します。

iterator begin() const

非同期例外リストの先頭へのイテレーターを返します。

iterator end() const

非同期例外リストの最後へのイテレーターを返します。

表 140. SYCL errc 列挙の値
標準 SYCL エラーコード

説明

success

実装は、このエラーコードで例外をスローすることはありません
が、ほかのエラーコードの値がゼロにならないように定義されています。アプリケーションは、このコードを使用して
std::error_code を作成して、「エラーではない」ことを示すことができます。

runtime

一般的なランタイムエラー。

kernelSYCL カーネルのキュー投入前、またはキュー投入中に発生したエラー。

第 4 章 SYCL プログラミング・インターフェイス | 309

SYCL 2020 リビジョン 6 - 4.13 エラー処理

標準 SYCL エラーコード

説明

nd_range

SYCL カーネルで指定された SYCL nd_range に関連するエラー

accessor

定義された SYCL アクセサーのオブジェクトに関連するエラー。

event

関連する SYCL event オブジェクトに関連するエラー。

kernel_argument

アプリケーションが SYCL カーネル関数に無効な引数を渡しました。SYCL カーネル関数がラムダ関数である場合、これにはキャプ
チャー変数が含まれます。

build

デバイスのカーネルバンドルをコンパイル、リンク、または構築する際に、オンラインコンパイルもしくはリンクで発生したエラー。

invalid

アプリケーションが無効なパラメーター値を SYCL API 関数に渡したり、SYCL API 関数を無効な方法で呼び出した際に使用されるキャッチオール・エラー。

memory_allocation

SYCL カーネルの SYCL デバイスで発生したメモリー割り当てエラー。

platform

SYCL プラットフォームがエラー発生時にこの例外をトリガーします。

profiling

プロファイル情報が有効である場合にエラーが発生すると、
SYCL ランタイムはこのエラーをトリガーします。

feature_not_supported

ホストコードがデバイスでサポートされないオプション機能を使用するとスローされる例外です。

kernel_not_supported

カーネルが、投入されたキューのデバイスでサポートされないオ
プション機能を使用するとスローされる例外です。この例外は、コマンドグループがカーネルバンドルにバインドされ、バンドルにコマンドグループから呼び出されたカーネルが含まれない場合にもスローされます。

backend_mismatch

アプリケーションは、バックエンドの情報が一致しないバックエ
ンド相互運用関数を呼び出しました。例えば、バックエンド B のSYCL オブジェクトからバックエンド A 固有の情報を要求すると、
このエラーが発生します。

表 141. SYCL エラーコードのヘルパー関数
SYCL エラーコードのヘルパー

説明

const std::error_category& sycl_category() noexcept;

SYCL エラーコードの静的エラー・カテゴリー・オブジェクトへの参照を取得します。このオブジェクトは、仮想関数
error_category::-name() をオーバーライドして文字列 “sycl” へのポインターを返します。実装がこのカテゴリーの
sycl::exception オブジェクト ex をスローする場合、例外に含まれるエラーコード値 (ex.code().value()) は、sycl::errc に列挙される値の 1 つです。

310 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

SYCL エラーコードのヘルパー

説明

std::error_code make_error_code(errc e) noexcept;e と sycl_category() を使用してエラーコードを生成します。

4.14. データタイプ
C++ プログラミング・モデルとしての SYCL は、C++ コア言語のデータタイプをサポートし、すべての SYCL アプリケーションを SYCL
互換デバイスで実行する機能を提供します。SYCL システムでサポートされるスカラーおよびベクトルのデータタイプを以下に示します。基本タイプとバックエンドの相互運用タイプに対する SYCL デバイス・コンパイラーのサポートに関する詳細については、5.5 節をご覧ください。

4.14.1. スカラー・データ・タイプ
SYCL でサポートされる C++ 基本データタイプを表 183 に示します。これらは基本タイプであるため、sycl 名前空間には存在しないことに注意してください。
sycl 名前空間で SYCL がサポートする追加のデータタイプを表 142 に示します。
表 142. SYCL でサポートされる追加のデータタイプ
スカラー・データ・タイプ

説明

byte

符号なし 8 ビット整数。C++17 std::byte が利用できるため
SYCL 2020 では非推奨になりました。

half

16 ビット浮動小数点。半精度データタイプは、IEEE 754-2008
半精度ストレージ形式に準拠する必要があります。このタイプはaspect::fp16 を持つデバイスでのみサポートされます。
std::numeric_limits は半精度データタイプ向けに特殊化されている必要があります。

4.14.2. ベクトルタイプ
SYCL は、SYCL デバイスおよびホスト C++ コードで効率良く機能するクロスプラットフォーム向けのクラス・テンプレートを提供します。このタイプはホストと SYCL デバイス間でベクトルを共有できます。ベクトルは、スウィズルされたコンポーネントのセットから新しいベクトルを構築するメンバーをサポートします。
vec<typename DataT, int NumElements> は、可能であれば SYCL デバイス上の SYCL バックエンドのビルトインタイプにコンパイルされ、可能でなければホストでの互換性をサポートするベクトルタイプです。vec クラスは、要素数と要素タイプに基づいてテンプ
レート化されます。要素数パラメーター NumElements は、1、2、3、4、8 または 16 のいずれかです。それ以外の値ではコンパイルに失敗します。要素タイプ・パラメーターDataT は、デバイスコードでサポートされる基本スカラータイプのいずれかでなければなりません。
SYCL vec クラス・テンプレートは、vector_t で定義される基本ベクトルタイプとの相互運用性を提供します。これは、デバイス向けのコンパイルでのみ利用できます。SYCL vec クラスは vector_t のインスタンスから構築でき、SYCL カーネル関数のネイティブ SYCL バッ
クエンド関数と相互運用をサポートするため、vector_t のインスタンスに暗黙的に変換できます。
単一要素のベクトルとスカラーを相互に変換できるよう、要素数が 1 の場合は SYCL vec クラス・テンプレートのインスタンスをデータ
タイプのインスタンスに暗黙的に変換できます。

第 4 章 SYCL プログラミング・インターフェイス | 311

SYCL 2020 リビジョン 6 - 4.14 データタイプ

4.14.2.1. Vec インターフェイスSYCL vec クラス・テンプレートのコンストラクター、メンバー関数、および非メンバー関数については、表 143、表 144 および表 145をご覧ください。
1.

namespace sycl {2.
3.

enum class rounding_mode : /* 未定義 */ {4.

automatic,

5.

rte,

6.

rtz,

7.

rtp,

8.

rtn

9.

};

10.
11.

struct elem {12.

static constexpr int x = 0;13.

static constexpr int y = 1;

14.

static constexpr int z = 2;

15.

static constexpr int w = 3;16.

static constexpr int r = 0;

17.

static constexpr int g = 1;18.

static constexpr int b = 2;

19.

static constexpr int a = 3;20.

static constexpr int s0 = 0;21.

static constexpr int s1 = 1;22.

static constexpr int s2 = 2;

23.

static constexpr int s3 = 3;24.

static constexpr int s4 = 4;25.

static constexpr int s5 = 5;26.

static constexpr int s6 = 6;27.

static constexpr int s7 = 7;28.

static constexpr int s8 = 8;29.

static constexpr int s9 = 9;30.

static constexpr int sA = 10;

31.

static constexpr int sB = 11;32.

static constexpr int sC = 12;33.

static constexpr int sD = 13;34.

static constexpr int sE = 14;

35.
36.

static constexpr int sF = 15;
};

37.
38.

template <typename DataT, int NumElements>

39.

class vec {40.

public:41.

using element_type = DataT;

42.
43.
44.
45.

#ifdef __SYCL_DEVICE_ONLY__
using vector_t = __unspecified__;#endif46.
47.

vec();

312 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ
48.
49.

explicit constexpr vec(const DataT& arg);

50.
51.

template <typename... ArgTN>

52.

constexpr vec(const ArgTN&... args);

53.
54.

constexpr vec(const vec<DataT, NumElements>& rhs);

55.
56.

#ifdef __SYCL_DEVICE_ONLY__

57.

vec(vector_t nativeVector);

58.
59.
60.

operator vector_t() const;#endif61.
62.

/*:NumElements == 1 の場合にのみ利用できます */63.

operator DataT() const;

64.
65.

static constexpr size_t byte_size() noexcept;

66.
67.

static constexpr size_t size() noexcept;

68.
69.

// 非推奨70.

size_t get_size() const;

71.
72.

// 非推奨73.

size_t get_count() const;

74.
75.

template <typename ConvertT, rounding_mode RoundingMode = rounding_mode::automatic>

76.

vec<ConvertT, NumElements> convert() const;

77.
78.

template <typename AsT>79.

AsT as() const;

80.
81.

template<int... swizzleIndexes>

82.

__swizzled_vec__ swizzle() const;

83.
84.

// NumElements <= 4 の場合にのみ利用できます85.

// XYZW_ACCESS は、x, y, z, w であり、NumElements の対象となります86.

__swizzled_vec__ XYZW_ACCESS() const;

87.
88.

/* NumElements == 4 の場合にのみ利用できます */89.

// RGBA_ACCESS は r, g, b, a です

90.

__swizzled_vec__ RGBA_ACCESS() const;

91.
92.

// INDEX_ACCESS は、s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD,

93.

// sE, sF, NumElements の対象となります。

94.

__swizzled_vec__ INDEX_ACCESS() const;

95.
96.

#ifdef SYCL_SIMPLE_SWIZZLES

97.

/* NumElements <= 4 の場合にのみ利用できます */98.

// XYZW_SWIZZLE は、NumElements の対象となる x, y, z, w の繰り返しを99.

// を伴うすべての順列です

第 4 章 SYCL プログラミング・インターフェイス | 313

SYCL 2020 リビジョン 6 - 4.14 データタイプ
100.

__swizzled_vec__ XYZW_SWIZZLE() const;

101.
102.

// NumElements == 4 の場合にのみ利用できます103.

// RGBA_SWIZZLE は、r, g, b, a の繰り返しによる順列です

104.

__swizzled_vec__ RGBA_SWIZZLE() const;

105.
106.

#endif // #ifdef SYCL_SIMPLE_SWIZZLES

107.
108.

/*: NumElements > 1 の場合にのみ利用できます */109.

__swizzled_vec__ lo() const;

110.

__swizzled_vec__ hi() const;

111.

__swizzled_vec__ odd() const;

112.

__swizzled_vec__ even() const;

113.
114.

// ロートとストアメンバー関数

115.

template <access::address_space AddressSpace, access::decorated IsDecorated>

116.

void load(size_t offset, multi_ptr<const DataT, AddressSpace, IsDecorated> ptr);

117.

template <access::address_space AddressSpace, access::decorated IsDecorated>

118.

void store(size_t offset, multi_ptr<DataT, AddressSpace, IsDecorated> ptr) const;

119.
120.

// 添字オペレーター

121.

DataT& operator[](int index);122.

const DataT& operator[](int index) const;

123.
124.

// OP は次のいずれかです: +, -, *, /, %125.

/* OP が % の場合、DataT != float && DataT != double

126.

&& DataT != half のときにのみ利用可能。*/

127.

vec operatorOP(const vec& lhs, const vec& rhs) { /* ... */ }128.

friend vec operatorOP(const vec& lhs, const DataT& rhs) { /* ... */ }

129.
130.

// OP は次のいずれかです: +=, -=, *=, /=, %=131.

/* OP が %= の場合、DataT != float && DataT != double132.

&& DataT != half のときにのみ利用可能。*/

133.

friend vec& operatorOP(vec& lhs, const vec& rhs) { /* ... */ }134.

friend vec& operatorOP(vec& lhs, const DataT& rhs) { /* ... */ }

135.
136.

// OP はプリフィクス ++, -- です137.

friend vec& operatorOP(vec& rhs) { /* ...*/ }

138.
139.

// OP はポストフィックス ++, -- です140.

friend vec operatorOP(vec& lhs, int) { /* ... */ }

141.
142.

// OP は単項の +, - です143.

friend vec operatorOP(const vec& rhs) { /* ... */ }

144.
145.

// OP は次のいずれかです: &, |, ^146.

/* DataT != float && DataT != double

147.

&& DataT != half のときにのみ利用可能。*/

148.

vec operatorOP(const vec& lhs, const vec& rhs) { /* ... */ }149.

friend vec operatorOP(const vec& lhs, const DataT& rhs) { /* ... */ }150.

314 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ
151.

// OP は次のいずれかです: &=, |=, ^=152.

/* DataT != float && DataT != double

153.

&& DataT != half のときにのみ利用可能。*/

154.

friend vec& operatorOP(vec& lhs, const vec& rhs) { /* ... */ }155.

friend vec& operatorOP(vec& lhs, const DataT& rhs) { /* ... */ }

156.
157.

// OP は次のいずれかです: &&, ||158.

friend vec<RET, NumElements> operatorOP(const vec& lhs, const vec& rhs) { /* ... */ }159.

friend vec<RET, NumElements> operatorOP(const vec& lhs, const DataT& rhs) { /* ... */ }

160.
161.

// OP is: <<, >>162.

/* Available only when: DataT != float && DataT != double

163.

&& DataT != half. */164.

friend vec operatorOP(const vec& lhs, const vec& rhs) { /* ... */ }165.

friend vec operatorOP(const vec& lhs, const DataT& rhs) { /* ... */ }

166.
167.

// OP is: <<=, >>=168.

/* Available only when: DataT != float && DataT != double

169.

&& DataT != half. */170.

friend vec& operatorOP(vec& lhs, const vec& rhs) { /* ... */ }171.

friend vec& operatorOP(vec& lhs, const DataT& rhs) { /* ... */ }

172.
173.

// OP is: ==, !=, <, >, <=, >=174.

friend vec<RET, NumElements> operatorOP(const vec& lhs, const vec& rhs) { /* ... */ }175.

friend vec<RET, NumElements> operatorOP(const vec& lhs, const DataT& rhs) { /* ... */ }

176.
177.

vec& operator=(const vec<DataT, NumElements>& rhs);

178.

vec& operator=(const DataT& rhs);

179.
180.

/* Available only when: DataT != float && DataT != double

181.

&& DataT != half. */182.

friend vec operator~(const vec& v) { /* ... */ }183.

friend vec<RET, NumElements> operator!(const vec& v) { /* ... */ }

184.
185.

// OP is: +, -, *, /, %186.

/* operator% is only available when: DataT != float && DataT != double &&187.

DataT != half. */188.

friend vec operatorOP(const DataT& lhs, const vec& rhs) { /* ... */ }

189.
190.

// OP is: &, |, ^191.

/* Available only when: DataT != float && DataT != double

192.

&& DataT != half. */193.

friend vec operatorOP(const DataT& lhs, const vec& rhs) { /* ... */ }

194.
195.

// OP is: &&, ||196.

friend vec<RET, NumElements> operatorOP(const DataT& lhs, const vec& rhs) { /* ... */ }

197.
198.

// OP is: <<, >>199.

/* Available only when: DataT != float && DataT != double

200.

&& DataT != half. */201.

friend vec operatorOP(const DataT& lhs, const vec& rhs) { /* ... */ }202.

第 4 章 SYCL プログラミング・インターフェイス | 315

SYCL 2020 リビジョン 6 - 4.14 データタイプ
203.

// OP is: ==, !=, <, >, <=, >=204.

friend vec<RET, NumElements> operatorOP(const DataT& lhs, const vec& rhs) { /* ... */ }

205.
206.

};

207.
208.

// デダクション・ガイド

209.

// 次のときにのみ利用可能: (std::is_same_v<T, U> && ...)

210.

template <class T, class...U>211.

vec(T, U...)-> vec<T, sizeof...(U) +

1>;

212.
213.

} // namespace sycl

表 143. SYCL vec クラス・テンプレートのコンストラクター
コンストラクター

説明

vec()

デフォルトでは、要素タイプ DataT と NumElements 次元数からベクトルを作成し、デフォルトで各要素を構築します。

explicit constexpr vec(const DataT& arg)

割り当てによりそれぞれの値を arg に設定することで、要素タイ
プ DataT と NumElements 次元数のベクトルを作成します。

template <typename... ArgTN>

同じ要素タイプのスカラー・パラメーターと SYCL vec パラメー

constexpr vec(const ArgTN&... args)

ターの任意の組み合わせから SYCL vec インスタンスを構築し、す べ て の パ ラ メ ー タ ー の 合 計 要 素 数 を vec 特 殊 化 のNumElements に提供します。

constexpr vec(const vec<DataT, NumElements>& rhs)

別 の ベ ク ト ル か ら コ ピ ー し て 、 要 素 タ イ プ DataT と 要 素 数
NumElements のベクトルを構築します。

vec(vector_t nativeVector)

デバイス向けにコンパイルされる場合にのみ利用できます。
vector_t で定義されるベースとなるバックエンド・ネイティブのベ
クトルタイプのインスタンスから、SYCL vec インスタンスを構築します。

表 144. SYCL vec クラス・テンプレートのメンバー関数
メンバー関数説明

operator vector_t() const

デバイス向けにコンパイルされる場合にのみ利用できます。
SYCL vec インスタンスを vector_t で定義されたベースとなる
バックエンド・ネイティブ・ベクトル・タイプに変換します。

operator DataT() const

NumElements == 1 の場合にのみ利用できます。
SYCL vec インスタンスを、この SYCL vec インスタンスの単一要
素の値を持つ DataT のインスタンスに変換します。
SYCL vec インスタンスは、同じデータタイプに暗黙的に変換でき、DataT は暗黙的に変換されます。暗黙的な変換を行う標準変換シーケンスを可能にするため、変換オペレーターをテンプレー
ト化してはならないことに注意してください。

static constexpr size_t size() noexcept

316 | 第 4 章 SYCL プログラミング・インターフェイスSYCL vec の要素数を返します。

SYCL 2020 リビジョン 6 - 4.14 データタイプ

メンバー関数説明

size_t get_count() const

size() と同じ値を返します。非推奨です。

static constexpr size_t byte_size() noexcept

SYCL vec のサイズをバイト単位で返します。
3 要素のベクトルサイズは、4 要素のベクトルサイズと一致し、OpenCL ベクトルタイプとの相互運用性を提供します。4.14.2.6
節で説明するのと同じ規則がベクトルのアライメントにも適用されます。

size_t get_size() const

byte_size() と同じ値を返します。非推奨です。

template<typename ConvertT, rounding_mode

SYCL vec を RoundingMode で 指 定 さ れ た 丸 め モ ー ド で 、RoundingMode = rounding_mode::automatic>

ConvertT で指定される別の要素タイプ SYCL vec に変換しま

vec<ConvertT, NumElements> convert() const

す。新しい SYCL vec タイプには、この SYCL vec と同じ数の要素が必要です。各種丸めモードを表 146 に示します。

template<typename asT> asT as() const

この SYCL vec を asT で指定される異なる要素タイプと要素数の
SYCL vec としてビット単位で再解釈します。新しい SYCL vec タ
イプには、この SYCL vec と同じストレージサイズ (バイト単位) が必要です。

template<int... swizzleIndexes>

4.14.2.4 節で説明するように、有効な式でスウィズルを適用する__swizzled_vec__ swizzle() const

際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。

__swizzled_vec__ XYZW_ACCESS() const

NumElements == 4 の場合にのみ利用できます。
4.14.2.4 節で説明するように、有効な式でスウィズルを適用する
際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
ここで、XYZW_ACCESS は、NumElements == 1 の場合は x、
NumElements == 2 である場合は x、y、NumElements == 3 の場合は x、y、z、そして NumElements == 4 の場合は x、y、z、w
です。

__swizzled_vec__ RGBA_ACCESS() const

NumElements == 4 の場合にのみ利用できます。
4.14.2.4 節で説明するように、有効な式でスウィズルを適用する
際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
RGBA_ACCESS は r、g、b、a です。

第 4 章 SYCL プログラミング・インターフェイス | 317

SYCL 2020 リビジョン 6 - 4.14 データタイプ

メンバー関数説明__swizzled_vec__ INDEX_ACCESS() const

4.14.2.4 節で説明するように、有効な式でスウィズルを適用する
際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
INDEX_ACCESS は次のいずれかです:
NumElements == 1 の場合は s0、
NumElements == 2 の場合は s0、s1、
NumElements == 3 の場合は s0、s1、s2、
NumElements == 4 の場合は s0、s1、s2、s3、
NumElements == 8 の場合は s0、s1、s2、s3、s4、s5、s6、s7、s8
および NumElements == 16 の場合は s0、s1、s2、s3、s4、s5、s6、s7、s8、s9、sA、sB、sC、sD、sE、sF。

__swizzled_vec__ XYZW_SWIZZLE() const

次 の 場 合 に の み 利 用 で き ま す : NumElements <= 4 で
SYCL_SIMPLE_SWIZZLES が <sycl/sycl.hpp> をインクルード
する前に定義されている場合。
4.14.2.4 節で説明するように、有効な式でスウィズルを適用する
際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
ここで、XYZW_SWIZZLE は、繰り返しのある並べ替えであり、レングスが 1 より大きいサブセットが NumElements == 2 である
場 合 は x 、 y 、 NumElements == 3 の 場 合 は x、 y 、 z 、 そして
NumElements == 4 の場合は x、y、z、w です。例えば、4 要素のvec は xzyw、xyyy および xz などの並べ替えを提供します。

__swizzled_vec__ RGBA_SWIZZLE() const

次 の 場 合 に の み 利 用 で き ま す : NumElements <= 4 で
SYCL_SIMPLE_SWIZZLES が <sycl/sycl.hpp> をインクルード
する前に定義されている場合。
4.14.2.4 節で説明するように、有効な式でスウィズルを適用する
際に使用できるインデックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
ここで RGBA_SWIZZLE は、r、g、b、a のレングスが 1 より大きなサブセットの繰り返しによりすべてを並べ替えます。例えば、4 要
素の vec は、rbga、rggg および rb を含む並べ替えを提供します。

__swizzled_vec__ lo() const

NumElements > 1 の場合にのみ利用できます。
4.14.2.4 節で説明されるように、有効な式でスウィズルを行うために利用できる、この SYCL vec の下位半分で構成されるイン
デックス・シーケンスを表す実装定義の中間クラス・テンプレート__swizzled_vec__ のインスタンスを返します。
NumElements == 3 の場合、この SYCL vec は、4 番目の要素が未定義の NumElements == 4 のように扱われます。

318 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

メンバー関数説明__swizzled_vec__ odd() const

NumElements > 1 の場合にのみ利用できます。
4.14.2.4 節で説明されるように、有効な式でスウィズルを行うために利用できる、この SYCL vec の奇数インデックスで構成されるインデックス・シーケンスを表す実装定義の中間クラス・テンプ
レート __swizzled_vec__ のインスタンスを返します。
NumElements == 3 の場合、この SYCL vec は、4 番目の要素が未定義の NumElements == 4 のように扱われます。

__swizzled_vec__ even() const

NumElements > 1 の場合にのみ利用できます。
4.14.2.4 節で説明されるように、有効な式でスウィズルを行うために利用できる、この SYCL vec の偶数インデックスで構成されるインデックス・シーケンスを表す実装定義の中間クラス・テンプ
レート __swizzled_vec__ のインスタンスを返します。
NumElements == 3 の場合、この SYCL vec は、4 番目の要素が未定義の NumElements == 4 のように扱われます。

template <access::address_space AddressSpace,

NumElements * offset による DataT タイプの要素の ptr オフ

access::decorated IsDecorated>

セットのアドレス値を、この SYCL vec のコンポーネントにロード

void load(size_t offset, multi_ptr<const DataT,します。

AddressSpace, IsDecorated> ptr)
template <access::address_space AddressSpace,

SYCL vec のコンポーネントを NumElements * offset によるaccess::decorated IsDecorated>

DataT タイプの要素の ptr オフセットのアドレスにストアします。

void store(size_t offset, multi_ptr<DataT, AddressSpace,
IsDecorated> ptr) const
DataT& operator[](int index)

index で指定されるインデックスで SYCL vec に格納されている要素への参照を返します。

const DataT& operator[](int index) const

index で指定されるインデックスで SYCL vec に格納されている要素への const 参照を返します。

vec& operator=(const vec& rhs)

rhs SYCL vec の各要素を SYCL vec に割り当てて、この SYCL
vec への参照を返します。

vec& operator=(const DataT& rhs)

rhs スカラーの各要素を SYCL vec に割り当てて、この SYCL vec
への参照を返します。

第 4 章 SYCL プログラミング・インターフェイス | 319

SYCL 2020 リビジョン 6 - 4.14 データタイプ
表 145. vec クラス・テンプレートの隠匿されたフレンド関数
隠匿されたフレンド関数

説明

vec operatorOP(const vec& lhs, const vec& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs vec と同一のテンプレート・パラメーターを使用して SYCLvec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
SYCL vec の各要素間ごとの OP 算術操作の結果です。
OP は次のいずれかです: +、-、*、/、%。

vec operatorOP(const vec& lhs, const DataT& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs vec と同じテンプレート・パラメーターを使用して SYCL vec
クラス・テンプレートの新しいインスタンスを構築します。新しいSYCL vec のインスタンスのそれぞれの要素は、lhs vec の各要素と rhs スカラー間の要素ごとの OP 算術操作の結果です。
OP は次のいずれかです: +、-、*、/、%。

vec& operatorOP(vec& lhs, const vec& rhs)

OP が %= 場 合 、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs vec の各要素と rhs SYCL vec の各要素間で、インプレースの要素ごとの OP 算術操作を実行して lhs vec を返します。
OP は次のいずれかです: +=、-=、*=、/=、%=。

vec& operatorOP(vec& lhs, const DataT& rhs)

OP が %= 場 合 、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs vec の各要素と rhs スカラーの各要素間で、インプレースの要
素ごとの OP 算術操作を実行して lhs vec を返します。
OP は次のいずれかです: +=、-=、*=、/=、%=。

vec& operatorOP(vec& v)

lhs vec の各要素にインプレースの要素ごとの OP プリフィクス算
術操作を実行して、各要素の結果を lhs vec の対応する要素に割り当てて lhs vec を返します。
OP は次のいずれかです: ++、--。

vec operatorOP(vec& v, int)

lhs vec の各要素にインプレースの要素ごとの OP ポストフィク
ス算術操作を実行して、各要素の結果を lhs vec の対応する要素に割り当てて、操作を実行すれる前に lhs vec のコピーを返します。
OP は次のいずれかです: ++、--。

320 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec& operatorOP(const vec& v)

SYCL vec と同じテンプレート・パラメーターを使用して、SYCL
vec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、この SYCL vec の各要素に対する要素ごとの OP 単項算術演算の結果です。
OP は次のいずれかです: +、-。

vec operatorOP(const vec& lhs, const vec& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec と同一のテンプレート・パラメーターを使用して SYCLvec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
SYCL vec の各要素間の OP ビット単位操作の結果です。
OP は次のいずれかです: &、|、^。

vec operatorOP(const vec& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec と同一のテンプレート・パラメーターを使用して SYCLvec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
スカラー間ごとの OP ビット単位操作の結果です。
OP は次のいずれかです: &、|、^。

vec& operatorOP(vec& lhs, const vec& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec の各要素と rhs SYCL vec の、インプレースの要素ごとのOP ビット演算を実行して lhs vec を返します。
OP は次のいずれかです: &=、|=、^=。

vec& operatorOP(vec& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec の各要素と rhs スカラーの各要素間で、インプレースの要
素ごとの OP ビット演算を実行して lhs vec を返します。
OP は次のいずれかです: &=、|=、^=。

第 4 章 SYCL プログラミング・インターフェイス | 321

SYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec<RET, NumElements> operatorOP(const vec& lhs,

lhs vec と同一のテンプレート・パラメーターを使用して SYCL

const vec& rhs)

vec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
SYCL vec の要素間ごとの OP 論理操作の結果です。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
は、SYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t、RET タイプおよび uint8_t の DataT を持つ SYCLvec は int8_t でなければなりません。int16_t、uint16_t またはhalf RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。 int32_t、 uint32_t または float RET タイプの
DataT を持つ SYCL vec は int32_t でなければなりません。
int64_t、uint64_t または double RET タイプの DataT を持つ
SYCL vec は int64_t でなければなりません。
OP は次のいずれかです: &&、||。

vec<RET, NumElements> operatorOP(const vec& lhs,

SYCL vec と同じテンプレート・パラメーターを使用して SYCL

const DataT& rhs)

vec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec のインスタンスの各要素は、lhs vec の各要素とrhs スカラー間の要素ごとの OP 論理操作の結果です。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
は、SYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t、RET タイプおよび uint8_t の DataT を持つ SYCLvec は int8_t でなければなりません。int16_t、uint16_t またはhalf RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。 int32_t、 uint32_t または float RET タイプの
DataT を持つ SYCL vec は int32_t でなければなりません。
int64_t、uint64_t または double RET タイプの DataT を持つ
SYCL vec は int64_t でなければなりません。
OP は次のいずれかです: &&、||。

vec operatorOP(const vec& lhs, const vec& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec と同一のテンプレート・パラメーターを使用して SYCLvec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
SYCL vec の要素間ごとの OP ビットシフト操作の結果です。OPが >> で DataT が符号付きタイプで lhs vec の値が負である場
合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<、>>。

322 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec operatorOP(const vec& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec と同一のテンプレート・パラメーターを使用して SYCLvec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs vec の各要素と rhs
スカラー要素間ごとの OP ビットシフト操作の結果です。OP が>> で DataT が符号付きタイプであり、lhs vec の値が負である場
合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<、>>。

vec& operatorOP(vec& lhs, const vec& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec の各要素と rhs SYCL vec の、インプレースの要素ごとのOP ビットシフト操作を実行して lhs vec を返します。OP が >>=で DataT が符号付きタイプで lhs vec の値が負である場合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<=、>>=。

vec& operatorOP(vec& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs vec の各要素と rhs スカラー要素間で、インプレースの要素
ごとの OP ビットシフト操作を実行して SYCL vec への参照を返します。OP が >>= で DataT が符号付きタイプで lhs vec の値が負である場合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<=、>>=。

第 4 章 SYCL プログラミング・インターフェイス | 323

SYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec<RET, NumElements> operatorOP(const vec& lhs,

新しい SYCL vec インスタンスの各要素を含む RET タイプを使

const vec& rhs)

用して SYCL vec クラス・テンプレートの新しいインスタンスを構築します。これは、lhs vec の各要素と rhs SYCL vec の要素間ごとの OP リレーショナル操作の結果です。
返される SYCL vec の各要素は、操作の結果が true の場合は 1、操作の結果が false の場合は 0 でなければなりません。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
は、SYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t、RET タイプおよび uint8_t の DataT を持つ SYCLvec は int8_t でなければなりません。int16_t、uint16_t またはhalf RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。 int32_t、 uint32_t または float RET タイプの
DataT を持つ SYCL vec は int32_t でなければなりません。
int64_t、uint64_t または double RET タイプの DataT を持つ
SYCL vec は uint64_t でなければなりません。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

vec<RET, NumElements> operatorOP(const vec& lhs,

RET の DataT パラメーターを使用して SYCL vec クラス・テンプ

const DataT& rhs)

レートの新しいインスタンスを構築します。新しい SYCL vec イン
スタンスの各要素は、lhs vec の各要素と rhs スカラー要素間ごとの OP リレーショナル操作の結果です。
返される SYCL vec の各要素は、操作の結果が true の場合は 1、そして結果が false の場合は 0 になります。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
は、SYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t、RET タイプおよび uint8_t の DataT を持つ SYCLvec は int8_t でなければなりません。int16_t、uint16_t またはhalf RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。 int32_t、 uint32_t または float RET タイプの
DataT を持つ SYCL vec は int32_t でなければなりません。
int64_t、uint64_t または double RET タイプの DataT を持つ
SYCL vec は uint64_t でなければなりません。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

324 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec operatorOP(const DataT& lhs, const vec& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
rhs SYCL vec と同じテンプレート・パラメーターを使用して、
SYCL vec クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL vec インスタンスの各要素は、lhs スカ
ラーと rhs SYCL vec の各要素間の要素ごとの OP 算術操作の結果です。
OP は次のいずれかです: +、-、*、/、%。

vec operatorOP(const DataT& lhs, const vec& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
rhs SYCL vec と同じテンプレート・パラメーターを使用して、
SYCL vec クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL vec インスタンスの各要素は、lhs スカ
ラーと rhs SYCL vec の各要素間の要素ごとの OP ビット操作の結果です。
OP は次のいずれかです: &、|、^。

vec<RET, NumElements> operatorOP(const DataT& lhs,

次のときにのみ利用可能: DataT != float && DataT != double

const vec& rhs)&& DataT != half。
rhs SYCL vec と同じテンプレート・パラメーターを使用して、
SYCL vec クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素は、lhs スカラーとrhs SYCL の要素間ごとの OP 論理演算の結果です。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
はSYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t および uint8_t RET タイプの DataT を持つ SYCLvec は int8_t でなければなりません。int16_t および uint16_t
RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。int32_t、uint32_t または float RET タイプの DataT を持つ SYCL vec は int32_t でなければなりません。int64_t、
uint64_t または double RET タイプの DataT を持つ SYCL vec
は uint64_t でなければなりません。
OP は次のいずれかです: &&、||。

vec operatorOP(const DataT& lhs, const vec& rhs)

rhs SYCL vec と同じテンプレート・パラメーターを使用して、
SYCL vec クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL vec インスタンスの各要素は、lhs スカ
ラーと rhs SYCL vec の各要素間の要素ごとの OP ビットシフト
操作の結果です。OP が >> で DataT が符号付きタイプで SYCL
vec の値が負である場合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットに 0 を設定します。
OP は次のいずれかです: <<、>>。

第 4 章 SYCL プログラミング・インターフェイス | 325

SYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec<RET, NumElements> operatorOP(const DataT& lhs,

次のときにのみ利用可能: DataT != float && DataT != double

const vec& rhs)&& DataT != half。
SYCL vec テンプレート・パラメーターの新しいインスタンスを構築します。新しい SYCL vec インスタンスの各要素を持つ要素タ
イプ RET は、lhs スカラーと rhs SYCL vec の要素間ごとの OP リ
レーショナル演算の結果です。
返される SYCL vec の各要素は、操作の結果が true の場合は-1、そして結果が false の場合は 0 になります。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
はSYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t および uint8_t RET タイプの DataT を持つ SYCLvec は int8_t でなければなりません。int16_t および uint16_t
RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。int32_t、uint32_t または float RET タイプの DataT を持つ SYCL vec は int32_t でなければなりません。int64_t、
uint64_t または double RET タイプの DataT を持つ SYCL vec
は int64_t でなければなりません。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

vec& operator~(const vec& v)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
v vec と同一のテンプレート・パラメーターを使用して SYCL vec
クラス・テンプレートの新しいインスタンスを構築します。新しいSYCL vec インスタンスの各要素は、v vec の要素ごとの OP ビッ
ト操作の結果です。

326 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明

vec<RET, NumElements> operator!(const vec& v)

v vec と同一のテンプレート・パラメーターを使用して SYCL vec
クラス・テンプレートの新しいインスタンスを構築します。新しいSYCL vec インスタンスの各要素は、v vec の要素ごとの OP 論理
操作の結果です。
返される SYCL vec の各要素は、操作の結果が true の場合は-1、結果が false の場合またはこの SYCL vec が NaN の場合は0 になります。
構築された SYCL vec の DataT テンプレート・パラメーター、RET
は、SYCL vec の DataT テンプレート・パラメーターによって異なります。int8_t タイプおよび uint8_t RET の DataT を持つ SYCLvec は int8_t でなければなりません。int16_t、uint16_t またはhalf RET タイプの DataT を持つ SYCL vec は int16_t でなければなりません。 int32_t、 uint32_t または float RET タイプの
DataT を持つ SYCL vec は int32_t でなければなりません。
int64_t、uint64_t または double RET タイプの DataT を持つ
SYCL vec は int64_t でなければなりません。

4.14.2.2. エイリアス
SYCL プログラミング API は、エイリアスタイプのすべての順列を提供します。
using <type><elems> = vec<<storage-type>, <elems>>
ここで、<elems> は 2、3、4、8 または 16 であり、整数タイプの <type> と <storage-type> のペアは char と int8_t、uchar と uint8_t、
short と int16_t、ushort と uint16_t、int と int32_t、uint と uint32_t、long と int64_t、ulong と uint64_t および浮動小数点タイプ
では両方とも half、float および double です。
例えば、uint4 は vec<uint32_t, 4> のエイリアスで、float16 は vec<float, 16> のエイリアスです。

4.14.2.3. スウィズル
スウィズル操作は2 つの方法で行われます。まず、swizzle メンバー関数テンプレートを呼び出します。
このテンプレートは、0 から NumElements-1 の間の可変数の整数テンプレート引数を受け取り、スウィズル・インデックスを返します。
次に、表 144 に XYZW_SWIZZLE と RGBA_SWIZZLE として定義される単純なスウィズルメンバー関数のいずれかを呼び出します。
単純なスウィズル関数は、4 つまでの要素ベクトルを操作でき、<sycl/sycl.hpp> をインクルードする前に SYCL_SIMPLE_SWIZZLES
マクロが定義されている場合にのみ使用できます。
どちらの場合も、戻り値タイプは常に __swizzled_vec__ のインスタンスであり、これは元の SYCL vec インスタンスのスウィズルを表す実装定義の一時クラスです。どちらの種類のスウィズルメンバー関数もスウィズル操作自体を実行してはなりません。式中で使用する
場合、__swizzled_vec__ から返されたインスタンスでスウィズル操作を行う必要があります。つまり、返された __swizzled_vec__ が式で使用されていないとスウィズル操作は行われません。
スウィズルメンバー関数テンプレートと単純なスウィズルメンバー関数の両方で、スウィズル・インデックスを繰り返しできます。
一連の静的 constexpr 値が elem 構造体に提供され、swizzle メンバー関数テンプレートを呼び出す際に名前付きスウィズル・イン
デックスを指定できるようにします。

第 4 章 SYCL プログラミング・インターフェイス | 327

SYCL 2020 リビジョン 6 - 4.14 データタイプ

4.14.2.4. スウィズル vec クラス__swizzled_vec__ クラスは、スウィズルメンバー関数を含む SYCL vec クラス・テンプレートのすべてのインターフェイスを提供する
未定義テンポラリーを定義する必要がありますが、これには次のような追加や変更があります。

• __swizzled_vec__ クラス・テンプレートは、式の RHS で r-value 参照として読み取り可能である必要があります。この場合、ス
ウィズル操作は式の RHS で実行され、結果は式の LHS に適用されます。

• __swizzled_vec__ クラス・テンプレートは、式の LHS で l-value 参照として代入可能である必要があります。この場合、式の RHS
は、__swizzled_vec__ がスウィズル操作を介して表現する元の SYCL vec に適用されます。
l-value 式で使用される __swizzled_vec__ には、繰り返しの要素インデックスを含めることができないことに注意してください。
例えば f4.xxxx() = fx.wzyx() は有効ではありません。

• __swizzled_vec__ クラス・テンプレートは、NumElements > 1 の場合、DataT タイプおよびスウィズルメンバー関数で指定される要素数を持つ SYCL vec のインスタンスに変換可能であり、NumElements == 1 の場合、DataT タイプのインスタンスに変換可能である必要があります。

• __swizzled_vec__ クラス・テンプレートは、コピー不可、移動不可、ユーザー構築不可でなければならず、l-value にバインドしたり、構築された式を取り消すことはできません。例えば、auso x = f4.x() は無効です。

• __swizzled_vec__ クラス・テンプレートは、vec<DataT, NumElements>& を返す vec クラス・テンプレート・インターフェイスから継承されたオペレーターごとに __swizzled_vec__& を返す必要があります。

4.14.2.5. 丸めモード
as メンバー関数テンプレートで使用できる丸めモードを表 146 に示します。
表 146. SYCL vec クラス・テンプレートの丸めモード
丸めモード

説明

automatic

SYCL vec クラス要素タイプのデフォルト丸めモードは、整数タイ
プでは rtz (ゼロに丸め) 、浮動小数点タイプでは rte (最も近い偶数に丸め) です。

rte

最も近い偶数に丸めます。

rtz

ゼロに丸めます。

rtp

正の無限大方向へ丸めます。

rtn

負の無限大方向へ丸めます。

4.14.2.6. メモリー配置とアライメント
SYCL vec クラス・テンプレートのインスタンス要素は、メモリーにシーケンシャルに連続して格納され、バイト単位の要素タイプのサイ
ズに要素数を掛けた値でアライメントされます。

328 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ
要素数が 3 の場合は特別です。この場合、SYCL vec はバイト単位の要素タイプのサイズに 4 を掛けた値でアライメントされます。

これは、vec クラス・テンプレートのインスタンスを SYCL カーネル関数に渡すため、ホストコードとデバイスコードの両方に適用されます。

4.14.2.7. パフォーマンスの注意点
一部のデバイスでは、添字 operator[] が効率良く使用できないことがあります。

4.14.3. 数学配列タイプ
SYCL は、連続する固定サイズのコンテナーを示す marray<typename DataT, std::size_t NumElements> クラス・テンプレートを提供します。このタイプはホストと SYCL デバイス間でコンテナーを共有できます。
marray クラスは、その要素タイプと要素数のテンプレートです。要素数パラメーター NumElements は、std::size_t タイプの正の値です。要素タイプ・パラメーター DataT は、C++ 標準で定義されるため数値タイプである必要があります。
単一要素の配列とスカラーを相互に変換できるよう、要素数が 1 の場合は marray クラス・テンプレートのインスタンスをデータタイ
プのインスタンスに暗黙的に変換できます。
marray クラス・テンプレートの論理および比較オペレーターは、marray<bool, NumElements> を返します。

4.14.3.1. 数学配列インターフェイスSYCL marray クラス・テンプレートのコンストラクター、メンバー関数、および非メンバー関数については、表 147、表 148 および表149 をご覧ください。
1.

namespace sycl {2.
3.

template <typename DataT, std::size_t NumElements>

4.

class marray {5.

public:6.

using value_type = DataT;

7.

using reference = DataT&;8.

using const_reference = const DataT&;

9.

using iterator = DataT*;

10.

using const_iterator = const DataT*;

11.
12.

marray();13.
14.

explicit constexpr marray(const DataT& arg);

15.
16.

template <typename... ArgTN>

17.

constexpr marray(const ArgTN&... args);

18.
19.

constexpr marray(const marray<DataT, NumElements>& rhs);

20.

constexpr marray(marray<DataT, NumElements>&& rhs);

21.
22.

/*:NumElements == 1 の場合にのみ利用できます */第 4 章 SYCL プログラミング・インターフェイス | 329

SYCL 2020 リビジョン 6 - 4.14 データタイプ
23.

operator DataT() const;

24.
25.

static constexpr std::size_t size() noexcept;

26.
27.

// 添字オペレーター

28.

reference operator[](std::size_t index);

29.

const_reference operator[](std::size_t index) const;

30.
31.

marray& operator=(const marray<DataT, NumElements>& rhs);

32.

marray& operator=(const DataT& rhs);

33.
34.

// イテレーター関数

35.

iterator begin();

36.

const_iterator begin() const;

37.
38.

iterator end();39.

const_iterator end() const;

40.
41.
42.

// OP は次のいずれかです: +, -, *, /, %43.

/* OP が % の場合、DataT != float && DataT != double && DataT != half でのみ利用できます。*/

44.

friend marray operatorOP(const marray& lhs, const marray& rhs) { /* ... */ }45.

friend marray operatorOP(const marray& lhs, const DataT& rhs) {/* ... */ }

46.
47.

// OP は次のいずれかです: +=, -=, *=, /=, %=48.

/* OP が %= の場合、DataT != float && DataT != double && DataT != half でのみ利用できます。*/

49.

friend marray& operatorOP(marray& lhs, const marray& rhs) { /* ... */ }50.

friend marray& operatorOP(marray& lhs, const DataT& rhs) { /* ... */ }

51.
52.

// OP はプリフィクス ++, -- です53.

friend marray& operatorOP(marray& rhs) { /* ... */ }

54.
55.

// OP はポストフィックス ++, -- です56.

friend marray operatorOP(marray& lhs, int) { /* ... */ }

57.
58.

// OP は単項の +, - です59.

friend marray operatorOP(marray& rhs) { /* ... */ }

60.
61.

// OP は次のいずれかです: &, |, ^62.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

63.

friend marray operatorOP(const marray& lhs, const marray& rhs) { /* ... */ }64.

friend marray operatorOP(const marray& lhs, const DataT& rhs) { /* ... */ }

65.
66.

// OP は次のいずれかです: &=, |=, ^=67.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

68.

friend marray& operatorOP(marray& lhs, const marray& rhs) { /* ... */ }69.

friend marray& operatorOP(marray& lhs, const DataT& rhs) { /* ... */ }

70.
71.

// OP は次のいずれかです: &&, ||72.

friend marray<bool, NumElements> operatorOP(const marray& lhs, const marray& rhs) { /* ...*/ }73.

friend marray<bool, NumElements> operatorOP(const marray& lhs, const DataT& rhs) { /* ...*/ }74.

330 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ
75.

// OP は次のいずれかです: <<, >>76.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

77.

friend marray operatorOP(const marray& lhs, const marray& rhs) { /* ... */ }78.

friend marray operatorOP(const marray& lhs, const DataT& rhs) { /* ... */ }

79.
80.

// OP は次のいずれかです: <<=, >>=81.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

82.

friend marray& operatorOP(marray& lhs, const marray& rhs) { /* ... */ }83.

friend marray& operatorOP(marray& lhs, const DataT& rhs) { /*... */ }

84.
85.

// OP は次のいずれかです: ==, !=, <, >, <=, >=86.

friend marray<bool, NumElements> operatorOP(const marray& lhs, const marray& rhs) { /* ...*/ }87.

friend marray<bool, NumElements> operatorOP(const marray& lhs, const DataT& rhs) { /* ...*/ }

88.
89.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

90.

friend marray operator~(const marray& v) { /* ... */ }

91.
92.

// OP は次のいずれかです: +, -, *, /, %93.

/* オペレーター * は DataT != float && DataT != double && DataT!= half のときにのみ利用可能 */94.

friend marray operatorOP(const DataT& lhs, const marray& rhs) { /* ... */ }

95.
96.

// OP は次のいずれかです: &, |, ^97.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能

98.

*/

99.

friend marray operatorOP(const DataT& lhs, const marray& rhs) { /* ... */ }

100.
101.

// OP は次のいずれかです: &&, ||102.

friend marray<bool, NumElements> operatorOP(const DataT& lhs, const marray& rhs) { /* ...*/ }

103.
104.

// OP は次のいずれかです: <<, >>105.

/* DataT != float && DataT != double && DataT != half のときにのみ利用可能*/

106.

friend marray operatorOP(const DataT& lhs, const marray& rhs) { /*... */ }

107.
108.

// OP は以下です: ==, !=, <, >, <=, >=109.

friend marray<bool, NumElements> operatorOP(const DataT& lhs, const marray& rhs) { /* ...*/ }

110.
111.

friend marray<bool, NumElements> operator!(const marray& v) { /* ... */ }

112.
113.

};

114.
115.

} // namespace sycl

表 147. SYCL marray クラス・テンプレートのコンストラクター
コンストラクター

説明marray()デフォルトでは、要素タイプ DataT と NumElements 次元数から配列を作成し、デフォルトで各要素を構築します。

explicit constexpr marray(const DataT& arg)

割り当てによりそれぞれの値を arg に設定することで、要素タイ
プ DataT と NumElements 次元数の配列を作成します。

第 4 章 SYCL プログラミング・インターフェイス | 331

SYCL 2020 リビジョン 6 - 4.14 データタイプ

コンストラクター

説明

template <typename... ArgTN>

同じ要素タイプのスカラー・パラメーターと SYCL marray パラ

constexpr marray(const ArgTN&... args)

メーターの任意の組み合わせから SYCL marray インスタンスを構築し、すべてのパラメーターの合計要素数を marray 特殊化の
NumElements に提供します。

constexpr marray(const marray<DataT, NumElements>&

別 の ベ ク ト ル か ら コ ピ ー し て 、 要 素 タ イ プ DataT と 要 素 数

rhs)

NumElements の配列を構築します。

constexpr marray(marray<DataT, NumElements>& rhs)

別 の ベ ク ト ル か ら 移 動 し て 、 要 素 タ イ プ DataT と 要 素 数
NumElements の配列を構築します。

表 148. SYCL marray クラス・テンプレートのメンバー関数
メンバー関数説明

operator DataT() const

NumElements == 1 の場合にのみ利用できます。
SYCL marray インスタンスを、この SYCL marray インスタンスの単一要素の値を持つ DataT のインスタンスに変換します。
SYCL marray インスタンスは、同じデータタイプに暗黙的に変換でき、DataT は暗黙的に変換されます。暗黙的な変換を行う標準
変換シーケンスを可能にするため、変換オペレーターをテンプ
レート化してはならないことに注意してください。

static constexpr std::size_t size() noexcept

SYCL marray のサイズをバイト単位で返します。

DataT& operator[](std::size_t index)

index で指定されるインデックスで SYCL marray に格納されている要素への参照を返します。

const DataT& operator[](std::size_t index) const

index で指定されるインデックスで SYCL marray に格納されている要素への const 参照を返します。

marray& operator=(const marray& rhs)

rhs SYCL marray の各要素を SYCL marray に割り当てて、このSYCL marray への参照を返します。

marray& operator=(const DataT& rhs)

rhs スカラーの各要素を SYCL marray に割り当てて、この SYCL
marray への参照を返します。

iterator begin()v marray に格納される最初の要素を参照するイテレーターを返します。

const_iterator begin() const

v marray に格納される最初の要素を参照する const イテレー
ターを返します。

iterator end()v marray に格納される最後の要素の 1 つ先を参照するイテレー
ターを返します。

const_iterator end() const

v marray に格納される最後の要素の 1 つ先を参照する const イ
テレーターを返します。

332 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ
表 149. marray クラス・テンプレートの隠匿されたフレンド関数
隠匿されたフレンド関数

説明marray operatorOP(const marray& lhs, const marray& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs marray と同一のテンプ レート・パラメーターを使用して
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タン ス の 各 要 素 は 、 lhs
marray の各要素と rhs SYCL marray の要素間ごとの OP 算術
操作の結果です。
OP は次のいずれかです: +、-、*、/、%。

marray operatorOP(const marray& lhs, const DataT& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs marray と同一のテンプ レート・パラメーターを使用して
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タン ス の 各 要 素 は 、 lhs
marray の各要素と rhs スカラー要素ごとの OP 算術操作の結果です。
OP は次のいずれかです: +、-、*、/、%。

marray& operatorOP(marray& lhs, const marray& rhs)

OP が %= 場 合 、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs marray の各要素と rhs SYCL marray の各要素間で、インプレースの要素ごとの OP 算術操作を実行して lhs marray を返します。
OP は次のいずれかです: +=、-=、*=、/=、%=。

marray& operatorOP(marray& lhs, const DataT& rhs)

OP が %= 場 合 、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
lhs marray の各要素と rhs スカラーの各要素間で、インプレースの要素ごとの OP 算術操作を実行して lhs marray を返します。
OP は次のいずれかです: +=、-=、*=、/=、%=。

marray& operatorOP(marray& v)

lhs marray の各要素にインプレースの要素ごとの OP プリフィク
ス算術操作を実行して、各要素の結果を lhs marray の対応する要素に割り当てて lhs marray を返します。
OP は次のいずれかです: ++、--。

marray operatorOP(marray& v, int)

lhs marray の各要素にインプレースの要素ごとの OP ポストフィ
クス算術操作を実行して、各要素の結果を lhs marray の対応する要素に割り当てて、操作を実行する前に lhs marray のコピーを返します。
OP は次のいずれかです: ++、--。

第 4 章 SYCL プログラミング・インターフェイス | 333

SYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明marray operatorOP(marray& v)

SYCL marray の各要素に対する要素ごとの OP 単項算術操作の結果を使用して、この SYCL marray インスタンスの要素から
SYCL marray と同一のテンプレート・パラメーターを使用して、
SYCL marray クラス・テンプレートの新しいインスタンスを構築します。
OP は次のいずれかです: +、-。

marray operatorOP(const marray& lhs, const marray& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray と同じテンプレート・パラメーターを使用して新しい
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タ ン ス の 各 要 素 は 、 lhs
marray の各要素と rhs SYCL marray の要素間ごとの OP ビット
操作の結果です。
OP は次のいずれかです: &、|、^。

marray operatorOP(const marray& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray と同じテンプレート・パラメーターを使用して新しい
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タ ン ス の 各 要 素 は 、 lhs
marray の各要素と rhs スカラー要素間ごとの OP ビット操作の結果です。
OP は次のいずれかです: &、|、^。

marray& operatorOP(marray& lhs, const marray& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray の各要素と rhs SYCL marray のインプレースの要素
ごとの OP ビット操作を実行して lhs marray を返します。
OP は次のいずれかです: &=、|=、^=。

marray& operatorOP(marray& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray の各要素と rhs スカラーの要素間でインプレースの要素ごとの OP ビット操作を実行して lhs marray を返します。
OP は次のいずれかです: &=、|=、^=。

marray<bool, NumElements> operatorOP(const marray&

DataT = bool および lhs marray と同じ NumElements を使用

lhs, const marray& rhs)

して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスのそれぞれの要素は、lhs
marray の各要素と rhs marray の要素間の要素ごとの OP 論理
操作の結果です。
OP は次のいずれかです: &&、||。

334 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明marray<bool, NumElements> operatorOP(const marray&

DataT = bool および lhs marray と同じ NumElements を使用

lhs, const DataT& rhs)

して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスのそれぞれの要素は、lhs
marray の各要素と rhs スカラー間の要素ごとの OP 論理操作の結果です。
OP は次のいずれかです: &&、||。

marray operatorOP(const marray& lhs, const marray& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray と同じテンプレート・パラメーターを使用して新しい
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タ ン ス の 各 要 素 は 、 lhs
marray の各要素と rhs SYCL marray の要素間ごとの OP ビット
シフト操作の結果です。OP が >> で、DataT が符号付きタイプでlhs marray の値が負である場合は符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<、>>。

marray operatorOP(const marray& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray と同じテンプレート・パラメーターを使用して新しい
SYCL marray クラス・テンプレートの新しいインスタンスを構築
し ま す 。 新 し い SYCL marray イ ン ス タ ン ス の 各 要 素 は 、 lhs
marray の各要素と rhs スカラー要素間ごとの OP ビットシフト
操作の結果です。OP が >> で DataT が符号付きタイプで lhs
marray の値が負である場合は、符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<、>>。

marray& operatorOP(marray& lhs, const marray& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray の各要素と rhs SYCL marray のインプレースの要素
ごとの OP ビットシフト操作を実行して lhs marray を返します。
OP が >>= で DataT が符号付きタイプで lhs marray の値が負である場合は、符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<=、>>=。

第 4 章 SYCL プログラミング・インターフェイス | 335

SYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明marray& operatorOP(marray& lhs, const DataT& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
lhs marray の各要素と rhs スカラー間で、インプレースの要素ごとの OP ビットシフト操作を実行して SYCL marray への参照を返します。OP が >>= であり DataT が符号付きタイプで lhs
marray の値が負である場合は、符号ビットに 1 を設定する必要があります。それ以外は、符号ビットには 0 を設定します。
OP は次のいずれかです: <<=、>>=。

marray<bool, NumElements> operatorOP(const marray&

DataT = bool および lhs marray と同じ NumElements を使用

lhs, const marray& rhs)

して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスの各要素は、lhs marray の各要素と rhs marray の要素間の要素ごとの OP リレーショナル
操作の結果です。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

marray<bool, NumElements> operatorOP(const marray&

DataT = bool および lhs marray と同じ NumElements を使用

lhs, const DataT& rhs)

して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスのそれぞれの要素は、lhs
marray の各要素と rhs スカラー間の要素ごとの OP リレーショ
ナル操作の結果です。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

marray operatorOP(const DataT& lhs, const marray& rhs)

OP が % の場合、 DataT != float && DataT != double &&DataT != half のときにのみ利用可能です。
rhs SYCL marray と同じテンプレート・パラメーターを使用して、
SYCL marray クラス・テンプレートの新しいインスタンスを作成して返します。新しい SYCL marray インスタンスの各要素は、lhs
スカラーと rhs SYCL marray の各要素間の要素ごとの OP オペ
レーターの結果です。
OP は次のいずれかです: +、-、*、/、%。

336 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.14 データタイプ

隠匿されたフレンド関数

説明marray operatorOP(const DataT& lhs, const marray& rhs)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
rhs SYCL marray と同じテンプレート・パラメーターを使用して、
SYCL marray クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL marray インスタンスの各要素は、lhs スカ
ラーと rhs SYCL marray の各要素間の要素ごとの OP ビット操
作の結果です。
OP は次のいずれかです: &、|、^。

marray<RET, NumElements> operatorOP(const DataT&

次のときにのみ利用可能: DataT != float && DataT != double

lhs, const marray& rhs)&& DataT != half。
DataT = bool および lhs marray と同じ NumElements を使用
して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスの各要素は、lhs スカラーとrhs marray の要素間の要素ごとの OP 論理操作の結果です。
OP は次のいずれかです: &&、||。

marray operatorOP(const DataT& lhs, const marray& rhs)

rhs SYCL marray と同じテンプレート・パラメーターを使用して、
SYCL marray クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL marray インスタンスの各要素は、lhs スカ
ラーと rhs SYCL marray の各要素間の要素ごとの OP ビットシ
フト操作の結果です。OP が >> で DataT が符号付きタイプで
SYCL marray の値が負である場合は、符号ビットに 1 を設定する必要があります。それ以外は、符号ビットに 0 を設定します。
OP は次のいずれかです: <<、>>。

marray<bool, NumElements> operatorOP(const DataT&

DataT = bool および lhs marray と同じ NumElements を使用

lhs, const marray& rhs)

して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい SYCL marray のインスタンスの各要素は、lhs スカ
ラーと rhs marray の要素間の要素ごとの OP リレーショナル操作の結果です。
lhs 要素または rhs 要素のいずれかが NaN の場合、==、<、>、<=、および >= 演算は false になります。 lhs 要素または rhs 要素のいずれかが NaN の場合、!= 演算の結果は true になります。
OP は次のいずれかです: ==、!=、<、>、<=、>=。

marray& operator~(const marray& v)

次のときにのみ利用可能: DataT != float && DataT != double&& DataT != half。
v marray と同一のテンプレート・パラメーターを使用して SYCL
marray クラス・テンプレートの新しいインスタンスを構築します。
新しい SYCL marray インスタンスの各要素は、v marray の要素
ごとの OP ビット操作の結果です。

第 4 章 SYCL プログラミング・インターフェイス | 337

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック

隠匿されたフレンド関数

説明marray<bool, NumElements> operator!(const marray& v)

DataT = bool および v marray と同じ NumElements を使用して、marray クラス・テンプレートの新しいインスタンスを構築します。新しい marray のインスタンスの各要素は、v marray の要素ごとの論理 ! 操作の結果です。

4.14.3.2. エイリアス
SYCL プログラミング API は、エイリアスタイプのすべての順列を提供します。
using m<type><elems> = marray<<storage-type>, <elems>>
ここで、<elems> は 2、3、4、8 または 16 であり、整数タイプの <type> と <storage-type> のペアは char と int8_t、uchar と uint8_t、
short と int16_t、ushort と uint16_t、int と int32_t、uint と uint32_t、long と int64_t、ulong と uint64_t および浮動小数点タイプ
では両方とも half、float および double、そしてブールタイプでは bool です。
例えば、muint4 は marray<uint32_t, 4> のエイリアスで、mfloat16 は marray<float, 16> のエイリアスです。

4.14.3.3. メモリー配置とアライメント
std::array<DataT, NumElements> に格納されるような marray クラス・テンプレートのインスタンスの要素。

4.15. 同期とアトミック
利用可能な機能には以下があります。

• アクセサークラス: アクセサークラスは、バッファーおよびイメージデータ構造の取得と解放を指定し、ベースとなるキュー同期プ
リミティブを作成する必要があるタイミングを提供します。

• アトミック操作: SYCL デバイスは C++ アトミックの限定されたサブセットをサポートし、SYCL は次の C++ 仕様のライブラリー
構文によってそれらを利用できるようにします。

• フェンス: フェンス・プリミティブは、ロードとストアを順序付けするために使用できます。それらは、atomic_fence 関数を通して公開されます。フェンスはセマンティクスの取得と解放、またはその両方を保持できます。

• バリア: バリア・プリミティブは、それぞれのグループ内の work-item を同期するために使用されます。それらは group_barrier 関数によって公開されます。

• 階層的な並列処理のディスパッチ: 計算を表現する階層並列処理モデルでは、work-group 内の同期は明示的な work-group バ
リア操作を使用せず、parallel_for_work_item 関数呼び出しの複数インスタンスを介して明示的に行われます。

• デバイスイベント: SYCL カーネル関数内で使用され、SYCL カーネル関数内の同期操作が完了するのを待機します。

4.15.1. バリアとフェンス
グループバリアまたはメモリーフェンスは、ローカルアドレス空間とグローバルアドレス空間の双方でメモリー順序付けセマンティクスを提供します。メモリーフェンスは、アトミック・オブジェクトを使用した同期と組み合わせると、関連するメモリーの順番付け (order)とメモリースコープ (scope) に従って、メモリーのロードとストア操作の並べ替えを制御します。
1.

namespace sycl {2.

338 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミック
3.

void atomic_fence(memory_order order, memory_scope scope);

4.
5.

} // namespace sycl

atomic_fence の呼び出しによる効果は、order パラメーターの値によって異なります。

• memory_order::relaxed: 影響なし
• memory_order::acquire: フェンスを取得• memory_order::release: フェンスを解放• memory_order::acq_rel: フェンスの取得と解放の両方• memory_order::seq_cst: シーケンシャルな一貫性のあるフェンスの取得と解放グループバリアはフェンスの取得とフェンスの解放の両方として機能します。グループ内のすべての work-item は、バリアで同期する前にフェンスの解放を実行し、グループ内のすべての work-item は、その後フェンスの取得を実行します。グループバリアは、内部的なアトミック・オブジェクトを介しているかのように、暗黙のアトミック同期を提供します。これにより、バリアに関連付けられたフェンスの取得とフェンスの解放が互いに同期されますが、フェンスを同期するためアトミック・オブジェクトで明示的なアトミック操作を行う必
要はありません。

4.15.2. device_event クラス
SYCL device_event クラスは、SYCL カーネル関数内でのみ利用でき、SYCL カーネル関数内の非同期操作の完了を待機するのに使用できる単一の SYCL デバイスイベントをカプセル化します。
device_event クラスのすべてのメンバー関数は、SYCL 例外をスローしてはなりません。
SYCL device_event クラスの概要を以下に示します。SYCL device_event クラスのコンストラクターとメンバー関数を表 150 と表151 に示します。
1.
2.

namespace sycl {class device_event {3.
4.

device_event( __unspecified__ );5.
6.

public:7.
8.
9.

void wait() noexcept;};} // namespace sycl

表 150. SYCL device_event クラスのメンバー関数
メンバー関数説明

void wait() noexcept

この SYCL device_event に関連付けられている非同期操作が完了するのを待機します。

表 151. device_event クラスのコンストラクター
コンストラクター説明

device_event(__unspecified__)

不特定の実装定義コンストラクター。

第 4 章 SYCL プログラミング・インターフェイス | 339

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック

4.15.3. アトミック参照
SYCL 仕様は、次の C++ 仕様のライブラリー構文に基づいたアトミック操作を提供します。サポートされる順序付けの機能はデバイスンに固有ですが、すべてのデバイスは少なくとも memory_order::relaxed をサポートすることが保証されます。デバイスごとに機能が異なるため、SYCL にはデフォルトの順序付けはなく、sycl::atomic_ref の各インスタンスで使用されるデフォルトの順序はテンプレー
ト引数で設定されます。デフォルトの順序が memory_order::relaxed に設定される場合、すべてのメモリー順序付け引数はデフォル
トで memory_order::relaxed になります。デフォルトの順序が memory_order::acq_rel に設定されている場合、メモリー順序付け
引数のデフォルトは、ロード操作では memory_order::acquire、ストア操作では memory_order::release、そして読み取り-変更-書き込み操作では memory_order::acq_rel になります。デフォルトの順序が memory_order::seq_cst に設定されている場合、すべてのメモリー順序付け引数はデフォルトで memory_order::seq_cst になります。
SYCL アトミック・ライブラリーは、SYCL アプリケーション・コードのベースとなる C++ ライブラリーに直接マップでき、ホストコードで利用する際は、ホスト C++ アトミック・ライブラリーと安全に作用する必要があります。機能が制限されたサブセットのみが確実に利用されるように、SYCL ライブラリーをデバイスコードで使用する必要があります。デバイスコードで std::atomic と std::atomic_ref クラスが使用されていると、SYCL デバイス・コンパイラーはコンパイルエラーとなります。
テンプレート・パラメーター space には、access::address_space::generic_space、access::address_space::global_space またはaccess::address_space::local_space が許可されます。
データタイプ T は、int、unsigned int、long、unsigned long、long long、unsigned long long、float または double にできます。浮
動 小 数 点 デ ー タ タ イ プ で は atomic_ref ク ラ ス の メ ン バ ー 関 数 を エ ミ ュ レ ー ト で き 、 info::device::single_fp_config お よ び
info::device::double_fp_config (浮動小数点アトミックは、異なる丸めモードを使用することがあり、例外動作も異なる場合があります) の定義とは異なる浮動小数点環境を使用できます。
アトミックタイプは次のように定義されます。
1.

namespace sycl {2.
3.

// 説明用途のみ

4.

template <memory_order ReadModifyWriteOrder>

5.

struct memory_order_traits;

6.
7.

template <>8.

struct memory_order_traits<memory_order::relaxed> {9.

static constexpr memory_order read_order = memory_order::relaxed;

10.

static constexpr memory_order write_order = memory_order::relaxed;

11.

};

12.
13.

template <>14.

struct memory_order_traits<memory_order::acq_rel> {15.

static constexpr memory_order read_order = memory_order::acquire;

16.
17.

static constexpr memory_order write_order = memory_order::release;
};

18.
19.

template <>20.

struct memory_order_traits<memory_order::seq_cst> {21.

static constexpr memory_order read_order = memory_order::seq_cst;

22.

static constexpr memory_order write_order = memory_order::seq_cst;

23.

};

24.

340 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミック25.

template <typename T, memory_order DefaultOrder, memory_scope DefaultScope, access::address_space
Space = access::address_space::generic_space>

26.

class atomic_ref {27.

public:28.
29.

using value_type = T;30.

static constexpr size_t required_alignment = /* 実装定義 */;31.

static constexpr bool is_always_lock_free = /* 実装定義 */;32.

static constexpr memory_order default_read_order = memory_order_traits<DefaultOrder>::read_order;

33.

static constexpr memory_order default_write_order = memory_order_traits<DefaultOrder>::write_order;

34.

static constexpr memory_order default_read_modify_write_order = DefaultOrder;

35.

static constexpr memory_scope default_scope = DefaultScope;

36.
37.

bool is_lock_free() const noexcept;

38.
39.

explicit atomic_ref(T&);

40.

atomic_ref(const atomic_ref&) noexcept;

41.

atomic_ref& operator=(const atomic_ref&) = delete;

42.
43.

void store(T operand,

44.

memory_order order = default_write_order,

45.

memory_scope scope = default_scope) const noexcept;

46.
47.

T operator=(T desired) const noexcept;

48.
49.

T load(memory_order order = default_read_order,

50.

memory_scope scope = default_scope) const noexcept;

51.
52.

operator T() const noexcept;

53.
54.

T exchange(T operand,

55.

memory_order order = default_read_modify_write_order,

56.

memory_scope scope = default_scope) const noexcept;

57.
58.

bool compare_exchange_weak(T& expected, T desired,59.

memory_order success,60.

memory_order failure,61.

memory_scope scope = default_scope) const noexcept;

62.
63.

bool compare_exchange_weak(T& expected, T desired,64.

memory_order order = default_read_modify_write_order,

65.

memory_scope scope = default_scope) const noexcept;

66.
67.

bool compare_exchange_strong(T& expected, T desired,68.

memory_order success,69.

memory_order failure,70.

memory_scope scope = default_scope) const noexcept;

71.
72.

bool compare_exchange_strong(T& expected, T desired,73.

memory_order order = default_read_modify_write_order,

74.

memory_scope scope = default_scope) const noexcept;

75.

};

第 4 章 SYCL プログラミング・インターフェイス | 341

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック
76.
77.

// 整数タイプに部分的な特殊化

78.

template <memory_order DefaultOrder, memory_scope DefaultScope,

79.

access::address_space Space = access::address_space::generic_space>

80.

class atomic_ref<Integral, DefaultOrder, DefaultScope, Space> {

81.
82.

/* atomic_ref<T> のほかのすべてのメンバーが利用できます */

83.
84.

using difference_type = value_type;

85.
86.

Integral fetch_add(Integral operand,87.

memory_order order = default_read_modify_write_order,

88.

memory_scope scope = default_scope) const noexcept;

89.
90.

Integral fetch_sub(Integral operand,91.

memory_order order = default_read_modify_write_order,

92.

memory_scope scope = default_scope) const noexcept;

93.
94.

Integral fetch_and(Integral operand,95.

memory_order order = default_read_modify_write_order,

96.

memory_scope scope = default_scope) const noexcept;

97.
98.

Integral fetch_or(Integral operand,99.

memory_order order = default_read_modify_write_order,

100.

memory_scope scope = default_scope) const noexcept;

101.
102.

Integral fetch_min(Integral operand,

103.

memory_order order = default_read_modify_write_order,

104.

memory_scope scope = default_scope) const noexcept;

105.
106.

Integral fetch_max(Integral operand,107.

memory_order order = default_read_modify_write_order,

108.

memory_scope scope = default_scope) const noexcept;

109.
110.

Integral operator++(int) const noexcept;

111.

Integral operator--(int) const noexcept;

112.

Integral operator++() const noexcept;

113.

Integral operator--() const noexcept;

114.

Integral operator+=(Integral) const noexcept;

115.

Integral operator-=(Integral) const noexcept;

116.

Integral operator&=(Integral) const noexcept;

117.

Integral operator|=(Integral) const noexcept;

118.

Integral operator^=(Integral) const noexcept;

119.
120.

};

121.
122.

// 浮動小数点タイプの部分的な特殊化

123.

template <memory_order DefaultOrder, memory_scope DefaultScope, access::address_space Space =access::address_space::generic_space>124.

class atomic_ref<Floating, DefaultOrder, DefaultScope, Space> {

125.
126.

/* atomic_ref<T> のほかのすべてのメンバーが利用できます */342 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミック
127.
128.

using difference_type = value_type;

129.
130.

Floating fetch_add(Floating operand,131.

memory_order order = default_read_modify_write_order,

132.

memory_scope scope = default_scope) const noexcept;

133.
134.

Floating fetch_sub(Floating operand,

135.

memory_order order = default_read_modify_write_order,

136.

memory_scope scope = default_scope) const noexcept;

137.
138.

Floating fetch_min(Floating operand,139.

memory_order order = default_read_modify_write_order,

140.

memory_scope scope = default_scope) const noexcept;

141.
142.

Floating fetch_max(Floating operand,143.

memory_order order = default_read_modify_write_order,

144.

memory_scope scope = default_scope) const noexcept;

145.
146.

Floating operator+=(Floating) const noexcept;

147.

Floating operator-=(Floating) const noexcept;

148.
149.

};

150.
151.

// ポインターの部分的な特殊化

152.

template <typename T, memory_order DefaultOrder, memory_scope DefaultScope,

153.

access::address_space Space = access::address_space::generic_space>154.

class atomic_ref<T*, DefaultOrder, DefaultScope, Space> {

155.
156.

using value_type = T*;

157.

using difference_type = ptrdiff_t;

158.

static constexpr size_t required_alignment = /* 実装定義 */;159.

static constexpr bool is_always_lock_free = /* 実装定義 */;160.

static constexpr memory_order default_read_order = memory_order_traits<DefaultOrder>::read_order;

161.

static constexpr memory_order default_write_order = memory_order_traits<DefaultOrder>::write_order;

162.

static constexpr memory_order default_read_modify_write_order = DefaultOrder;

163.

static constexpr memory_scope default_scope = DefaultScope;

164.
165.

bool is_lock_free() const noexcept;

166.
167.

explicit atomic_ref(T*&);168.

atomic_ref(const atomic_ref&) noexcept;

169.

atomic_ref& operator=(const atomic_ref&) = delete;

170.
171.

void store(T* operand,172.

memory_order order = default_write_order,

173.

memory_scope scope = default_scope) const noexcept;

174.
175.

T* operator = (T* desired) const noexcept;

176.
177.
178.

T* load(memory_order order = default_read_order,
memory_scope scope = default_scope) const noexcept;

第 4 章 SYCL プログラミング・インターフェイス | 343

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック
179.
180.

operator T*() const noexcept;

181.
182.

T* exchange(T* operand,

183.

memory_order order = default_read_modify_write_order,

184.

memory_scope scope = default_scope) const noexcept;

185.
186.

bool compare_exchange_weak(T*& expected, T* desired,187.

memory_order success,188.

memory_order failure,189.

memory_scope scope = default_scope) const noexcept;

190.
191.

bool compare_exchange_weak(T*& expected, T* desired,

192.

memory_order order = default_read_modify_write_order,

193.

memory_scope scope = default_scope) const noexcept;

194.
195.

bool compare_exchange_strong(T*& expected, T* desired,196.

memory_order success,197.

memory_order failure,198.

memory_scope scope = default_scope) const noexcept;

199.
200.

bool compare_exchange_strong(T*& expected, T* desired,201.

memory_order order = default_read_modify_write_order,

202.

memory_scope scope = default_scope) const noexcept;

203.
204.

T* fetch_add(difference_type,205.

memory_order order = default_read_modify_write_order,

206.

memory_scope scope = default_scope) const noexcept;

207.
208.

T* fetch_sub(difference_type,209.

memory_order order = default_read_modify_write_order,

210.

memory_scope scope = default_scope) const noexcept;

211.
212.

T* operator++(int) const noexcept;

213.

T* operator--(int) const noexcept;

214.

T* operator++() const noexcept;

215.

T* operator--() const noexcept;

216.

T* operator+=(difference_type) const noexcept;

217.

T* operator-=(difference_type) const noexcept;

218.
219.

};

220.
221.

} // namespace sycl

SYCL atomic_ref クラスのコンストラクターとメンバー関数のインスタンスを表 152 と表 153 に示します。整数、浮動小数点、およびポインタータイプの追加のメンバー関数を表 154、表 155 および表 156 に示します。
静的メンバー required_alignment では、atomic_ref<T> で参照できるオブジェクトの最小アライメント要件をバイト単位で指定します。これは少なくとも alignof(T) である必要があります。
タイプ T のすべてのアトミック操作が常にロックフリーである場合、静的メンバー is_always_lock_free は true です。

344 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミック
SYCL 実装では、ロックフリーではないアトミック操作のサポートが保証されていません。
静的メンバー default_read_order、default_write_order および default_read_modify_write_order は、DefaultOrder テンプレー
トと一致するそれぞれのタイプのアトミック操作のメモリー順序値を反映します。
アトミック操作とメンバー関数は、上記の制限を除き C++ 仕様で説明されるように動作します。SYCL では work-item 間の前方処理が保証されていないため、アトミックを使用して同期ルーチンを実装するには注意が必要です。コードがポータブルである場合、workitem の処理を進行するため、別の work-item に依存してはなりません。
表 152. SYCL atomic_ref クラス・テンプレートのコンストラクター
コンストラクター

説明atomic_ref(T& ref)ref に関連付けられている SYCL atomic_ref のインスタンスを構築します。

表 153. atomic_ref<T> タイプの任意のオブジェクトで利用可能なメンバー関数
メンバー関数説明

bool is_lock_free() const

atomic_ref によって提供されるアトミック操作がロックフリーの場合、true を返します。

void store(T operand,

atomic_ref で参照されるオブジェクトに operand をアトミック

memory_order order = default_write_order,に格納します。このアトミック操作のメモリー順序は、

memory_scope scope = default_scope) const

memory_order::relaxed 、 memory_order::release ま た は
memory_order::seq_cst である必要があります。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

T operator=(T desired) const

store(desired) と同等です。desired を返します。

T load(atomic_ref で参照されるオブジェクトの値をアトミックにロード

memory_order order = default_read_order

します。このアトミック操作のメモリー順序は、

memory_scope scope = default_scope) const

memory_order::relaxed 、 memory_order::acquire ま た は
memory_order::seq_cst である必要があります。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

operator T() const

load() と同等です。

T exchange(T operand,

こ の atomic_ref に よ っ て 参 照 さ れ る オ ブ ジ ェ ク ト の 値 を

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

operand の値にアトミックに置き換え、参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバ
イス上の 64 ビット・データ・タイプでのみサポートされます。

第 4 章 SYCL プログラミング・インターフェイス | 345

SYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

bool compare_exchange_weak(T& expected, T desired,

こ の atomic_ref に よ っ て 参 照 さ れ る オ ブ ジ ェ ク ト の 値 を

memory_order success,expected の値とアトミックに比較します。値が等しい場合、参照

memory_order failure,

されるオブジェクトの値を desired の値に置き換えようとします。

memory_scope scope = default_scope) const

それ以外は、参照されるオブジェクトの元の値を expected の値に割り当てます。
比較操作と置き換え操作が成功すると true を返します。このアト
ミ ッ ク 操作 に 失 敗 す るメ モ リーの 順序 付け は 、memory_order::relaxed 、 memory_order::acquire ま た は
memory_order::seq_cst である必要があります。
この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・
データ・タイプでのみサポートされます。

bool compare_exchange_weak(T& expected, T desired,memory_order order =compare_exchange_weak(expected, desired, order, order,
scope) と同等です。

default_read_modify_write_order,
memory_scope scope = default_scope) const
bool compare_exchange_strong(T& expected, T desired,

こ の atomic_ref に よ っ て 参 照 さ れ る オ ブ ジ ェ ク ト の 値 を

memory_order success,expected の値とアトミックに比較します。値が等しい場合、参照

memory_order failure,

されるオブジェクトの値を desired の値に置き換えようとします。

memory_scope scope = default_scope) const

それ以外は、参照されるオブジェクトの元の値を expected の値に割り当てます。
比較操作が成功すると true を返します。このアトミック操作に失敗 す る メ モ リ ー の 順 序 付 け は 、 memory_order::relaxed 、
memory_order::acquire または memory_order::seq_cst である必要があります。
この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・
データ・タイプでのみサポートされます。

bool compare_exchange_strong(T& expected, T desired,memory_order order =compare_exchange_strong(expected, desired, order, order,
scope) と同等です。

default_read_modify_write_order) const
表 154. 整数 T の atomic_ref<T> タイプのオブジェクトで利用可能な追加のメンバー関数
メンバー関数説明

T fetch_add(T operand,

この atomic_ref で参照されるオブジェクトの値に operand の

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

値をアトミックに加算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T operator+=(T operand) const

fetch_add(operand) + operand と同等です。

T operator++(int) const

fetch_add(1) と同等です。

T operator++() const

fetch_add(1) + 1 と同等です。

346 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

T fetch_sub(T operand,

この atomic_ref で参照されるオブジェクトの値から operand の

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

値をアトミックに減算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T operator-=(T operand) const

fetch_sub(operand) - operand と同等です。

T operator--(int) const

fetch_sub(1) と同等です。

T operator--() const

fetch_sub(1) - 1 と同等です。

T fetch_and(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

でアトミックにビット単位の論理積を実行し、その結果を参照さ
れるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T operator&=(T operand) const

fetch_and(operand)& operand と同等です。

T fetch_or(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

でアトミックにビット単位の論理和を実行し、その結果を参照さ
れるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T operator|=(T operand) const

fetch_or(operand) と同等です。

T fetch_xor(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

でアトミックにビット単位の排他論理和を実行し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイ
ス上の 64 ビット・データ・タイプでのみサポートされます。

T operator^=(T operand) const

fetch_xor(operand) と同等です。

T fetch_min(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

でアトミックに最小値を計算し、その結果を参照されるオブジェ
クトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T fetch_max(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =でアトミックに最大値を計算し、その結果を参照されるオブジェ

default_read_modify_write_order,
memory_scope scope = default_scope) const

クトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

第 4 章 SYCL プログラミング・インターフェイス | 347

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック
表 155. 浮動小数点 T の atomic_ref<T> タイプのオブジェクトで利用可能な追加のメンバー関数
メンバー関数説明

T fetch_add(T operand,

この atomic_ref で参照されるオブジェクトの値に operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

をアトミックに加算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数
は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タ
イプでのみサポートされます。

T operator+=(T operand) const

fetch_add(operand) + operand と同等です。

T fetch_sub(T operand,

この atomic_ref で参照されるオブジェクトの値から operand の

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

値をアトミックに減算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T operator-=(T operand) const

fetch_sub(operand) - operand と同等です。

T fetch_min(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

でアトミックに最小値を計算し、その結果を参照されるオブジェ
クトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T fetch_max(T operand,

この atomic_ref で参照されるオブジェクトの値と operand の値

memory_order order =でアトミックに最大値を計算し、その結果を参照されるオブジェ

default_read_modify_write_order,
memory_scope scope = default_scope) const

クトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

表 156. atomic_ref<T*> タイプの任意のオブジェクトで利用可能な追加のメンバー関数
メンバー関数説明

T* fetch_add(ptrdiff_t operand,

この atomic_ref で参照されるオブジェクトの値に operand の値

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

をアトミックに加算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数
は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タ
イプでのみサポートされます。

T* operator+=(ptrdiff_t operand) const

fetch_add(operand) + operand と同等です。

T* operator++(int) const

fetch_add(1) と同等です。

T* operator++() const

fetch_add(1) + 1 と同等です。

T* fetch_sub(ptrdiff_t operand,

この atomic_ref で参照されるオブジェクトの値から operand の

memory_order order =default_read_modify_write_order,
memory_scope scope = default_scope) const

値をアトミックに減算し、その結果を参照されるオブジェクトに割り当てます。参照されるオブジェクトの元の値を返します。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

348 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

T* operator-=(ptrdiff_t operand) const

fetch_sub(operand) - operand と同等です。

T* operator--(int) const

fetch_sub(1) と同等です。

T* operator--() const

fetch_sub(1) - 1 と同等です。

4.15.4. アトミックタイプ (非推奨)
SYCL 1.2.1 で提供されるアトミックタイプとアトミックタイプの操作は、SYCL 2020 では非推奨となり、SYCL の将来のバージョンでは削除される予定です。タイプと操作は、下位互換のため cl::sycl:: 名前空間で利用できます。
cl::sycl::atomic クラスのコンストラクターとメンバー関数を表 157 と表 158 に示します。
1.

namespace cl {2.

namespace sycl {3.
4.

/* SYCL 2020 では非推奨 */5.

enum class memory_order : /* 未定義 */ {6.
7.

relaxed};8.
9.

/* SYCL 2020 では非推奨 */10.

template <typename T, access::address_space AddressSpace =11.

access::address_space::global_space>

12.

class atomic {13.

public:14.

template <typename PointerT, access::decorated IsDecorated>

15.

atomic(multi_ptr<PointerT, AddressSpace, IsDecorated> ptr);

16.
17.
18.

void store(T operand, memory_order memoryOrder =memory_order::relaxed);

19.
20.

T load(memory_order memoryOrder = memory_order::relaxed) const;

21.
22.
23.

T exchange(T operand, memory_order memoryOrder =memory_order::relaxed);

24.
25.

/* 次のときにのみ利用可能: T != float */26.

bool compare_exchange_strong(T& expected, T desired,27.

memory_order successMemoryOrder = memory_order::relaxed,

28.

memory_order failMemoryOrder = memory_order::relaxed);

29.
30.

/* 次のときにのみ利用可能: T != float */31.

T fetch_add(T operand, memory_order memoryOrder =32.

memory_order::relaxed);

33.
34.

/* 次のときにのみ利用可能: T != float */35.

T fetch_sub(T operand, memory_order memoryOrder =36.

memory_order::relaxed);

37.

第 4 章 SYCL プログラミング・インターフェイス | 349

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック38.

/* 次のときにのみ利用可能: T != float */39.

T fetch_and(T operand, memory_order memoryOrder =40.

memory_order::relaxed);

41.
42.

/* 次のときにのみ利用可能: T != float */43.

T fetch_or(T operand, memory_order memoryOrder =44.

memory_order::relaxed);

45.
46.

/* 次のときにのみ利用可能: T != float */47.

T fetch_xor(T operand, memory_order memoryOrder =48.

memory_order::relaxed);

49.
50.

/* 次のときにのみ利用可能: T != float */51.

T fetch_min(T operand, memory_order memoryOrder =52.

memory_order::relaxed);

53.
54.

/* 次のときにのみ利用可能: T != float */55.

T fetch_max(T operand, memory_order memoryOrder =

56.
57.

memory_order::relaxed);
};

58.
59.

} // namespace sycl

60.

} // namespace clグローバル関数は次のとおりで、表 159 で説明します。
1.

namespace cl {2.

namespace sycl {3.

/* SYCL 2020 では非推奨 */4.

template <typename T, access::address_space AddressSpace>5.

void atomic_store(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder =6.

memory_order::relaxed);

7.
8.

/* SYCL 2020 では非推奨 */9.

template <typename T, access::address_space AddressSpace>10.

T atomic_load(atomic<T, AddressSpace> object, memory_order memoryOrder =11.

memory_order::relaxed);

12.
13.

/* SYCL 2020 では非推奨 */14.

template <typename T, access::address_space AddressSpace>

15.

T atomic_exchange(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

16.

memory_order::relaxed);

17.
18.

/* SYCL 2020 では非推奨 */19.

template <typename T, access::address_space AddressSpace>20.

bool atomic_compare_exchange_strong(atomic<T, AddressSpace> object, T& expected, T desired,21.

memory_order successMemoryOrder = memory_order::relaxed,

22.

memory_order failMemoryOrder = memory_order::relaxed);

23.
24.

/* SYCL 2020 では非推奨 */25.

template <typename T, access::address_space AddressSpace>26.

T atomic_fetch_add(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

350 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミック
27.

memory_order::relaxed);

28.
29.

/* SYCL 2020 では非推奨 */30.

template <typename T, access::address_space AddressSpace>31.

T atomic_fetch_sub(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

32.

memory_order::relaxed);

33.
34.

/* SYCL 2020 では非推奨 */35.

template <typename T, access::address_space AddressSpace>36.

T atomic_fetch_and(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

37.

memory_order::relaxed);

38.
39.

/* SYCL 2020 では非推奨 */40.

template <typename T, access::address_space AddressSpace>41.

T atomic_fetch_or(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

42.

memory_order::relaxed);

43.
44.

/* SYCL 2020 では非推奨 */45.

template <typename T, access::address_space AddressSpace>46.

T atomic_fetch_xor(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

47.

memory_order::relaxed);

48.
49.

/* SYCL 2020 では非推奨 */50.

template <typename T, access::address_space AddressSpace>51.

T atomic_fetch_min(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

52.

memory_order::relaxed);

53.
54.

/* SYCL 2020 では非推奨 */55.

template <typename T, access::address_space AddressSpace>56.

T atomic_fetch_max(atomic<T, AddressSpace> object, T operand, memory_order memoryOrder=

57.

memory_order::relaxed);

58.

} // namespace sycl

59.

} // namespace cl

表 157. cl::sycl::atomic クラス・テンプレートのコンストラクター
コンストラクター

説明

template <typename pointerT>SYCL 2020 では非推奨です。

atomic(multi_ptr<pointerT, AddressSpace> ptr)

pointerT で許可されるデータタイプは、T と同じバイト単位サイ
ズの有効なスカラー・データー・タイプです。データタイプ T のポイ
ンターに変換された、ポインター ptr に関連付けられた SYCL
atomic のインスタンスを構築します。

第 4 章 SYCL プログラミング・インターフェイス | 351

SYCL 2020 リビジョン 6 - 4.15 同期とアトミック
表 158. cl::sycl::atomic<T> タイプのオブジェクトで利用可能なメンバー関数
メンバー関数説明

void store(T operand, memory_order memoryOrder =SYCL 2020 では非推奨です。

memory_order::relaxed)

この SYCL atomic に関連付けられた multi_ptr のアドレスのoperand 値をアトミックに格納します。このアトミック操作のメ
モリー順序は memory_order::relaxed でなければなりません。
この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・
データ・タイプでのみサポートされます。

T load(memory_order memoryOrder =memory_order::relaxed) const

SYCL 2020 では非推奨です。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値をアトミックにロードし ます。 呼び出し前に、この SYCL
atomic に関連付けられた multi_ptr のアドレスにある値を返します。
このアトミック操作のメモリー順序は memory_order::relaxed
でなければなりません。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

T exchange(T operand, memory_order memoryOrder=
memory_order::relaxed)

SYCL 2020 では非推奨です。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を operand の値にアトミックに置き換え、呼び出し前に、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。
このアトミック操作のメモリー順序は memory_order::relaxed
でなければなりません。この関数は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプでのみサポートされます。

bool compare_exchange_strong(T& expected, T desired,memory_order successMemoryOrder =memory_order::relaxed,

SYCL 2020 では非推奨です。
次のときにのみ利用可能: T != float。

memory_order failMemoryOrder =この SYCL atomic に関連付けられた multi_ptr のアドレスにあmemory_order::relaxed)

る値と expected の値をアトミックに比較します。値が等しい場
合、この SYCL atomic に関連付けられている multi_ptr のアドレスにある値を desired の値に置き換えます。それ以外は、SYCL
atomic に関連付けられている multi_ptr のアドレスにある値をexpected の値に置き換えます。比較操作が成功すると true を返します。このアトミック操作のメモリー順序は、成功しても失敗しても memory_order::relaxed である必要があります。この関数
は、aspect::atomic64 を持つデバイス上の 64 ビット・データ・タ
イプでのみサポートされます。

352 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

T fetch_add(T operand, memory_order memoryOrder =SYCL 2020 では非推奨です。

memory_order::relaxed)

次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に operand の値をアトミックに加算し、この SYCL atomicに関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

T fetch_sub(T operand, memory_order memoryOrder =memory_order::relaxed)

SYCL 2020 では非推奨です。
次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値から operand の値をアトミックに減算し、この SYCL atomicに関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

T fetch_and(T operand, memory_order memoryOrder =memory_order::relaxed)

SYCL 2020 では非推奨です。
次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値と operand の値をアトミックにビット単位の論理積を実行
し、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

第 4 章 SYCL プログラミング・インターフェイス | 353

SYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

T fetch_or(T operand, memory_order memoryOrder =SYCL 2020 では非推奨です。

memory_order::relaxed)

次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値と operand の値をアトミックにビット単位の論理和を実行
し、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

T fetch_xor(T operand, memory_order memoryOrder =memory_order::relaxed)

SYCL 2020 では非推奨です。
次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値と operand の値をアトミックにビット単位の排他論理和を実行し、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

T fetch_min(T operand, memory_order memoryOrder =memory_order::relaxed)

SYCL 2020 では非推奨です。
次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値から operand の値の最小値を計算し、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。この SYCL atomic に関連付けられた multi_ptr のアドレスに あ る値 を 返 し ま す 。 こ の アト ミ ッ ク操 作 の メ モ リ ー 順 序 は
memory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

354 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.15 同期とアトミックメンバー関数説明

T fetch_max(T operand, memory_order memoryOrder =SYCL 2020 では非推奨です。

memory_order::relaxed)

次のときにのみ利用可能: T != float。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値から operand の値の最大値を計算し、この SYCL atomic に関連付けられた multi_ptr のアドレスにある値に結果を割り当てます。
この SYCL atomic に関連付けられた multi_ptr のアドレスにある値を返します。このアトミック操作のメモリー順序はmemory_order::relaxed でなければなりません。この関数は、
aspect::atomic64 を持つデバイス上の 64 ビット・データ・タイプ
でのみサポートされます。

表 159. アトミックタイプで使用可能なグローバル関数
関数

説明

template <typename T, access::address_space

SYCL 2020 では非推奨です。

AddressSpace>
T atomic_load(atomic<T, AddressSpace> object,

object.load(memoryOrder) 呼び出しと同等。

memory_order memoryOrder = memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>void atomic_store(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.store(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_exchange(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.exchange(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>bool atomic_compare_exchange_strong(
atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.compare_exchange_strong(expected, desired,successMemoryOrder, failMemoryOrders) 呼び出しと同等。

T& expected, T desired,memory_order successMemoryOrder =memory_order::relaxed
memory_order failMemoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_add(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.fetch_add(operand, memoryOrder) 呼び出しと同等。

T operand,memory_order memoryOrder =memory_order::relaxed)

第 4 章 SYCL プログラミング・インターフェイス | 355

SYCL 2020 リビジョン 6 - 4.16 ストリームクラス関数

説明

template <typename T, access::address_space

SYCL 2020 では非推奨です。

AddressSpace>
T atomic_fetch_sub(atomic<T, AddressSpace> object,

object.fetch_sub(operand, memoryOrder) 呼び出しと同等。

T operand,memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_and(atomic<T> operand, T object,

SYCL 2020 では非推奨です。
object.fetch_add(operand, memoryOrder) 呼び出しと同等。

memory_order memoryOrder = memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_or(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.fetch_or(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_xor(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.fetch_xor(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_min(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.fetch_min(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)
template <typename T, access::address_space
AddressSpace>
T atomic_fetch_max(atomic<T, AddressSpace> object,

SYCL 2020 では非推奨です。
object.fetch_max(operand, memoryOrder) 呼び出しと同等。

T operand, memory_order memoryOrder =memory_order::relaxed)

4.16. ストリームクラス
SYCL stream クラスは、バッファリングされた出力ストリームであり、ビルトイン、ベクトル、および SYCL タイプの値をコンソール出力できます。値をコンソールにストリーミングする実装の詳細は、実装の方法として残されています。
SYCL stream クラスのインスタンスによって値が出力される過程は、マニピュレーターを使用して変更することもできます。
stream クラスには 2 つの制限があります。totalBufferSize には、カーネルを呼び出している間に出力できる文字ストリーム全体の最大サイズを指定します。また、workItemBufferSize には、フラッシュを行う前に work-item 内で出力できる文字ストリームの最大サイズを指定します。これらの制限値はバイト単位で指定します。totalBufferSize の制限値には、カーネルを呼び出し中に (すべての workitem からの出力) すべてのストリーム文によって出力される文字数を十分に格納できるサイズでなければなりません。また、
workItemBufferSize の制限値は、フラッシュ前にストリーム間の work-item 内の出力文字数十分に格納できるサイズである必要があります。

356 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.16 ストリームクラス
totalBufferSize または workItemBufferSize の制限値を超えた場合、制限を超えたストリームの文字を出力するか、無視/廃棄するか
は実装定義です。また、出力する場合、workItemBufferSize の制限を超えた文字列が totalBufferSize の制限にカウントされるかど
うかは実装定義となります。制限を超えた文字を出力する実装定義の動作にかかわりなく、制限を超えた文字の実装での未定義な、または誤った動作は 許可されません。 workItemBufferSize 内の未使用の文字数 (ストリームのフラッシュで使用されなかった
workItemBufferSize 容量の一部) は、totalBufferSize の制限値にカウントされず、フラッシュされた文字のみが totalBufferSize の制限にカウントされます。
SYCL stream クラスは、共通の参照セマンティクスを提供します (4.5.2 節を参照)。

4.16.1. ストリーム・クラス・インターフェイスSYCL stream クラスのコンストラクターとメンバー関数を表 162、表 163 および表 164 に示します。追加の共通特殊メンバー関数と共通メンバー関数については、表 7 と表 8 を参照してください。
SYCL stream クラスの operator<<() オペレーターでサポートされるオペランドを表 160 に示します。
SYCL stream クラスの operator<<() オペレーターでサポートされるマニピュレーターを表 161 に示します。
1.

namespace sycl {2.
3.

enum class stream_manipulator : /* 未定義 */ {4.

flush,

5.

dec,

6.

hex,

7.

oct,

8.

noshowbase,9.

showbase,10.

noshowpos,

11.

showpos,

12.

endl,

13.

fixed,

14.

scientific,

15.

hexfloat,

16.

defaultfloat

17.

};

18.
19.
20.

const stream_manipulator flush = stream_manipulator::flush;

21.
22.

const stream_manipulator dec = stream_manipulator::dec;

23.
24.

const stream_manipulator hex = stream_manipulator::hex;

25.
26.

const stream_manipulator oct = stream_manipulator::oct;

27.
28.

const stream_manipulator noshowbase = stream_manipulator::noshowbase;

29.
30.

const stream_manipulator showbase = stream_manipulator::showbase;

31.
32.

const stream_manipulator noshowpos = stream_manipulator::noshowpos;

33.

第 4 章 SYCL プログラミング・インターフェイス | 357

SYCL 2020 リビジョン 6 - 4.16 ストリームクラス
34.

const stream_manipulator showpos = stream_manipulator::showpos;

35.
36.

const stream_manipulator endl = stream_manipulator::endl;

37.
38.

const stream_manipulator fixed = stream_manipulator::fixed;

39.
40.

const stream_manipulator scientific = stream_manipulator::scientific;

41.
42.

const stream_manipulator hexfloat = stream_manipulator::hexfloat;

43.
44.

const stream_manipulator defaultfloat = stream_manipulator::defaultfloat;

45.
46.

__ｐｒecision_manipulator__ ｓetprecision(int precision);

47.
48.

__width_manipulator__ ｓetw(int width);

49.
50.

class stream {51.

public:52.
53.

stream(size_t totalBufferSize, size_t workItemBufferSize, handler& cgh

54.

const property_list& propList = {});

55.
56.

/* -- 共通インターフェイスのメンバー -- */57.

/* プロパティー・インターフェイスのメンバー */

58.
59.
60.

size_t size() const noexcept;

61.
62.

// 非推奨63.

size_t get_size() const;

64.
65.

size_t get_work_item_buffer_size() const;

66.
67.

/* get_max_statement_size() は、get_work_item_buffer_size() と同じ機能を持ち、68.

下位互換のため提供されます。 get_max_statement_size() は非推奨です*/

69.
70.
71.

size_t get_max_statement_size() const;
};

72.
73.

template <typename T>

74.

const stream& operator<<(const stream& os, const T& rhs);

75.
76.

} // namespace sycl

表 160. stream クラスでサポートされるオペランドタイプ
ストリーム・オペランド・タイプ

説明char、signed char、unsigned char、int、unsigned int、short、

値を文字ストリームとして出力します。

unsigned short、long int、unsigned long int、long long int、
unsigned long long int

358 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.16 ストリームクラス

ストリーム・オペランド・タイプ

説明float、double、half

現在の文の精度に応じた値を文字ストリームとして出力します。

char*、const char*

文字列を出力します。

T*、const T*、multi_ptr

ポインターのアドレスを文字ストリームとして出力します。

vec

ベクトルの各コンポーネントの値を文字ストリームとして出力します。

id、range、item、nd_item、group、nd_range、h_item

各 id またはレンジの各コンポーネントの値を文字ストリームとして出力します。

表 161. stream クラスでサポートされるマニピュレーター
ストリーム・マニピュレーター

説明

flush

フラッシュ操作をトリガーします。これにより、work-item スト
リームバッファーがグローバル・ストリーム・バッファーと同期され、work-item ストリームバッファーは空になります。フラッシュが完了すると、workItemBufferSize は work-item.内の後続のストリームを再び利用できるようになります。

endl

改行文字を出力してからフラッシュ操作をトリガーします。

dec

現在の文の後続の値を 10 進数で出力します。

hex

現在の文の後続の値を 16 進数で出力します。

oct

現在の文の後続の値を 8 進数で出力します。

noshowbase

ベース・プリフィクスなしで後続の値を出力します。

showbase

ベース・プリフィクス付きで後続の値を出力します。

noshowpos

値が正である場合、後続の値をプラス記号なしで出力します。

showpos

値が正である場合、後続の値をプラス記号付きで出力します。

setw(int)

現在の文の後続の値フィールドの幅を設定します。

setprecision(int)

現在の文の後続の値の精度を設定します。

fixed

現在の文の後続の浮動小数点値を固定表記で出力します。

scientific

現在の文の後続の浮動小数点値を科学表記で出力します。

hexfloat

現在の文の後続の浮動小数点値を 16 進表記で出力します。

defaultfloat

現在の文の後続の浮動小数点値をデフォルト表記で出力します。

第 4 章 SYCL プログラミング・インターフェイス | 359

SYCL 2020 リビジョン 6 - 4.16 ストリームクラス
表 162. stream クラスのコンストラクター
コンストラクター

説明stream(size_t totalBufferSize,

cgh によって指定されたコマンドグループに関連付けられた SYCL

size_t workItemBufferSize,

stream インスタンスを構築して、パラメーター totalBufferSize でhandler& cgh,

カーネル呼び出しごとの最大バッファーサイズをバイト単位で指定

const property_list& propList = {})し、パラメーター workItemBufferSize でストリームのフラッシュ
間で work-item がバッファーできる最大ストリームのサイズを指定します。ゼロ個以上のプロパティーを property_list のインスタン
スを介して構築された SYCL stream に提供できます。

表 163. stream クラスのメンバー関数
メンバー関数説明

size_t size() const noexcept

合計バッファーサイズをバイト単位で返します。

size_t get_size() const

size() と同じ値を返します。非推奨です。

size_t get_work_item_buffer_size() const

work-item ごとのバッファーサイズをバイト単位で返します。

size_t get_max_statement_size() const

get_work_item_buffer_size() と同等の機能を持つ非推奨のクエリー。

表 164. stream クラスのグローバル関数
グローバル関数説明

template <typename T> const stream& operator<<(const

有効な値 (表 160 を参照)を文字ストリームとして出力し、有効なstream& os, const T& rhs)

マニピュレーター (表 161 を参照) を現在のストリームに適用します。

4.16.2. 同期
SYCL stream クラスのインスタンスはホストとの同期に必要であり、コマンドグループの送信に関連付けられたイベントが完了状態になるまでに、SYCL カーネル関数内のフラッシュ操作 (workItemBufferSize や totalBufferSize の制限を超えない) の前に、
operator<<() オペレーターを介してストリームされたすべてを出力する必要があります。この同期が発生するポイントと、同期が行われるメンバー関数は実装定義です。例えば、実装で printf() を使用することは有効です。
SYCL stream クラスは、フラッシュとフラッシュの間 (workItemBufferSize 以内で)、ほかの work-item からのコンテンツと混在することなく、それぞれのストリームのコンテンツを出力するために必要となります。work-item またはストリーム間におけるほかの出力順
序の保証はありません。ストリームのフラッシュ操作は、単一ストリームに対してほかの work-item と混在なく表示されるように、出力単位が区切られます。

4.16.3. 暗黙のフラッシュ
各 work-item の観点から、カーネル実行の最後にカーネルによって使用されるそれぞれのストリームの暗黙的なフラッシュが保証されます。endl ストリーム・マニピュレーターが実行されると、暗黙のフラッシュが行われます。実装では、その他の暗黙的なフラッシュは許可されていません。

360 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

4.16.4. パフォーマンスの注意点
stream クラスはデバッグ用途に設計されているため、パフォーマンスが重要なアプリケーションでの使用は推奨されません。

4.17. SYCL ホストとデバイス向けの SYCL ビルトイン関数
SYCL カーネルは任意のデバイスで実行できますが、これにはカーネルで使用される関数をコンパイルして、デバイスとホストの両方にリンクする必要があります。SYCL プログラミング・モデルでは、ビルトインは sycl 名前空間の SYCL アプリケーション全体で使用できますが、セマンティクスは異なることがあります。このセクションでは、『OpenCL 1.2 仕様』の 6.12 節 (SYCL ではすべての関数はsycl 名前空間にある) に準拠する、SYCL ホストとデバイスにおけるこれらの関数の動作について説明します。期待される精度とそのほかのセマンティクスの要件は、バックエンド仕様で定義されます。
SYCL ビルトイン関数は SYCL アプリケーション全体で利用できますが、実行する場所に応じてホスト実装またはデバイス実装が使用されます。SYCL システムは、すべてのビルトイン関数がホストとデバイスの双方で同じ要件を満たすことを保証します。

4.17.1. SYCL ホストおよびデバイスで利用可能なビルトインタイプの説明
すべての OpenCL ビルトインタイプは、sycl 名前空間で利用できます。このドキュメントでは、有効な SYCL タイプのセットを表現するためジェネリック・タイプ名を使用します。ジェネリック・タイプ名自体は有効な SYCL タイプではありませんが、表 165 に定義されているように有効なタイプセットを表します。このセクション内の各ジェネリック・タイプは、スカラー、SYCL vec および marray クラスの特殊化の組み合わせで構成されます。{n} と {N} は、クラスの特殊化で有効なサイズを定義します。ここで、{n} は 2、3、4、8、16 のいずれかであり、{N} は size_t タイプの正の値です。
基本タイプの参照は、スカラー、または SYCL vec か marray 特殊化の要素タイプを示すことに注意してください。
表 165. カーネル関数へのパラメーターの有効なタイプの表現として機能する一般的なタイプ名の説明
ジェネリック・タイプ名

説明

floatnfloat{n}、mfloat{n}、marray<{N},float>

genfloatf

float、floatn

doublendouble{n}、mdouble{n}、marray<{N},double>

genfloatd

double、doublen

halfn

half{n}、mhalf{n}、marray<{N},half>

genfloath

half、halfn

genfloat

genfloatf、genfloatd、genfloath

sgenfloat

float、double、half

vgenfloat

float{n}、double{n}、half{n}mgenfloat

marray<float,{n}>、marray<double,{n}>、marray<half,{n}>gengeofloat

float、float2、float3、float4、mfloat2、mfloat3、mfloat4

第 4 章 SYCL プログラミング・インターフェイス | 361

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

ジェネリック・タイプ名

説明

gengeodouble

double、double2、double3、double4、mdouble2、
mdouble3、mdouble4

charn

char{n}、mchar{n}、marray<{N},char>scharnschar{n}、mschar{n}、marray<{N},signed char>ucharnuchar{n}、muchar{n}、marray<{N},unsigned char>scharnschar{n}、mschar{n}、marray<{N},signed char>ucharnuchar{n}、muchar{n}、marray<{N},unsigned char>igencharsigned char、scharn

ugencharunsigned char、ucharn

gencharchar、charn、igenchar、ugenchar

shortnshort{n}、mshort{n}、marray<{N},short>

genshort

short、shortn

ushortn

ushort{n}、mushort{n}、marray<{N},unsigned short>ugenshortunsigned short、ushortn

uintn

uint{n}、muint{n}、marray<{N},unsigned int>

ugenint

unsigned int、uintn

intn

int{n}、mint{n}、marray<{N},int>

genintint、intn

ulongnulong{n}、mulong{n}、marray<{N},unsigned long int>

ugenlong

unsigned long int、ulongn

longn

long{n}、mlong{n}、marray<{N},long int>

genlonglong int、longn

ulonglongn

ulonglong{n}、mulonglong{n}、marray<{N},unsigned long
long int>

ugenlonglong

unsigned long long int、ulonglongn

longlongn

longlong{n}、mlonglong{n}、marray<{N},long long int>

genlonglong

long long int、longlongn

igenlonginteger

genlong、genlonglong

ugenlonginteger

ugenlong、ugenlonglong362 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

ジェネリック・タイプ名

説明

geninteger

genchar、genshort、ugenshort、genint、ugenint、
igenlonginteger、ugenlonginteger

genintegerNbit

基本タイプのサイズが N ビットである geninteger のすべてのタイ
プ (N = 8、16、32、64)。

igeninteger

igenchar、genshort、genint、igenlongintegerigenintegerNbit

基本タイプのサイズが N ビットである igeninteger のすべてのタ
イプ (N = 8、16、32、64)。

sigeninteger

signed char、short、int、long int、long long int

vigeninteger

schar{n}、short{n}、int{n}、long{n}、longlong{n}migeninteger

marray<signed

char,{n}>、marray<short,{n}>、marray<int,{n}>、marray<long,{n}>、marray<longlong,{n}>ugeninteger

ugenchar、ugenshort、 ugenint、ugenlonginteger

ugenintegerNbit

基本タイプのサイズが N ビットである ugeninteger のすべてのタ
イプ (N = 8、16、32、64)。

sugeninteger

unsigned char、unsigned short、unsigned int、unsigned long
int、unsigned long long int

vugeninteger

uchar{n}、ushort{n}、uint{n}、ulong{n}、ulonglong{n}mugeninteger

marray<unsigned char,{n}>、marray< unsigned short,{n}>、marray< unsigned int,{n}>、marray< unsigned long int,{n}>、marray< unsigned long long int,{n}>sgeninteger

char、sigeninteger、sugeninteger

vgeninteger

char {n}、vigeninteger、vugeninteger

mgeninteger

marray<char, {n}>、migeninteger、mugeninteger

gentypegenfloat、geninteger

sgentype

sgenfloat、sgeninteger

vgentype

vgenfloat、vgeninteger

mentypemgenfloat、mgeninteger

genfloatptr

multi_ptr<DataT, AddressSpace, IsDecorated> のすべての順 列 で す 。 こ こ で DataT は genfloat 内 の す べて の タイ プ 、AddressSpace は access::address_space::global_space 、
access::address_space::local_space とspace::private_space お よ びaccess::address_

IsDecorated は 、 access::

decorated::yes および access::decorated::no です。

第 4 章 SYCL プログラミング・インターフェイス | 363

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

ジェネリック・タイプ名

説明

genintptr

multi_ptr<DataT, AddressSpace, IsDecorated> のすべての順 列 で す 。 こ こ で DataT は genint 内 の す べ て の タ イ プ 、AddressSpace は access::address_space::global_space 、
access::address_space::local_space と access::address_
space::private_space お よ び IsDecorated は 、 access::
decorated::yes および access::decorated::no です。

boolnmarray<{N},bool>

genboolbool、booln

4.17.2. 関数オブジェクト
SYCL は、ホストとデバイスの sycl 名前空間で、多数の関数オブジェクトを提供します。すべての関数オブジェクトは、C++ の変換とプ
ロモーション規則に従います。各関数オブジェクトは、パラメーター・タイプと戻り値タイプを推測する透過な関数オブジェクトとして
void を特殊化します。
1.

namespace sycl {2.
3.

template <typename T=void>4.

struct plus {5.
6.

T operator()(const T& x, const T& y) const;
};

7.
8.

template <typename T=void>9.

struct multiplies {

10.
11.

T operator()(const T& x, const T& y) const;
};

12.
13.

template <typename T=void>

14.

struct bit_and {

15.
16.

T operator()(const T& x, const T& y) const;
};

17.
18.

template <typename T=void>

19.

struct bit_or {

20.
21.

T operator()(const T& x, const T& y) const;
};

22.
23.

template <typename T=void>

24.

struct bit_xor {

25.
26.

T operator()(const T& x, const T& y) const;
};

27.
28.

template <typename T=void>29.

struct logical_and {

30.
31.

T operator()(const T& x, const T& y) const;};

32.

364 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
33.

template <typename T=void>

34.

struct logical_or {

35.
36.

T operator()(const T& x, const T& y) const;
};

37.
38.

template <typename T=void>

39.

struct minimum {

40.
41.

T operator()(const T& x, const T& y) const;
};

42.
43.

template <typename T=void>

44.

struct maximum {

45.
46.

T operator()(const T& x, const T& y) const;
};

47.
48.

} // namespace sycl

表 166. plus 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x + y に等価な引数の合計を返します。

表 167. multiplies 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x * y に等価な引数の積を返します。

表 168. bit_and 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x & y に等価な引数のビット単位 AND を返します。

表 169. bit_or 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x | y に等価な引数のビット単位 OR を返します。

表 170. bit_xor 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) constx ^ y に等価な引数のビット単位 XOR を返します。

表 171. logical_and 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x && y に等価な引数の論理 AND を返します。

第 4 章 SYCL プログラミング・インターフェイス | 365

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
表 172. logical_or 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

x || y に等価な引数の論理 OR を返します。

表 173. minimum 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

小さな値の変数を返します。引数が等しい場合、最初の引数を返します。

表 174. maximum 関数オブジェクトのメンバー関数
メンバー関数説明

T operator()(const T& x, const T& y) const

大きな値の変数を返します。引数が等しい場合、最初の引数を返します。

4.17.3. グループ関数
SYCL は、work-item のグループに関連付けられた機能を公開する関数を提供します (グループバリアや集合操作など)。これらのグループ関数は同期ポイントとして機能し、グループ内のすべての work-item が収束制御フローで到達する必要があります。グループ
内の単一 work-item がグループ関数を呼び出す場合、そのグループ内のすべての work-item は同一の条件で同じ関数を呼び出す必要があります。異なる条件で同じ関数を呼び出すと (ループまたは条件付き文の異なる分岐など) 動作は未定義となります。さらに、グループ内のすべての work-item が実行中の操作と同調することを保証するため、それぞれの関数に渡される引数を制限することができます。関数に渡される引数に関する制限は、関数内の説明で定義されます。これらの制限に違反すると動作は未定義となります。
すべてのグループ関数は、SYCL によってサポートされる基本スカラータイプ (表 183 参照) および SYCL vec と marray クラスのインスタンスでサポートされます。
カーネル内でグループ関数を使用すると、同じカーネル内のユーザーコードが利用できるリソースに制限が生じる可能性があります。
これらの制限の動作は実装定義ですが、4.11.12.1 節で説明するように、カーネルの照会関数 (kernel_bundle::get_kernel_info など)に反映されている必要があります。
parallel_for_work_group や parallel_for_work_item コンテキストから呼び出されるグループ関数の動作は未定義です。

4.17.3.1. グループタイプの特性
1.

namespace sycl {2.

template <class T>

3.

struct is_group;4.
5.

template <class T>

6.

inline constexpr bool is_group_v = is_group<T>::value;7.

}

is_group タイプの特性は、グループ関数でサポートされるグループのタイプを決定し、グループ関数のオーバーロードの解決に参加するタイミングを制御します。

366 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
T が標準 SYCL グループ (group または sub_group) タイプである場合、is_group<T> は std::true_type であり、それ以外は
std::false_type となります。これらのタイプのインターフェイスがすべてのメンバー関数と group および sub_group クラスで共通の静的メンバーをサポートする場合、SYCL の実装は実装定義のグループタイプの is_group<T> に追加の特殊化を導入することがあります。

4.17.3.2. group_broadcast
group_broadcast 関数は、1 つの work-item が保持する値をグループ内のほかのすべての work-item にブロードキャストします。
1.

template <typename Group, typename T>

2.

T group_broadcast(Group g, T x); // (1)3.
4.

template <typename Group, typename T>

5.

T group_broadcast(Group g, T x, Group::linear_id_type local_linear_id); // (2)6.
7.

template <typename Group, typename T>

8.

T group_broadcast(Group g, T x, Group::id_type local_id); // (3)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、T が容易にコピー可能である場合にのみ利用できます。
戻り値: グループ内で最小の線形 id を持つ work-item からの x の値。

2.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、T が容易にコピー可能である場合にのみ利用できます。
前提条件: グループ内のすべての work-item 間で local_linear_id が同一である必要があります。
戻り値: グループ内で指定された線形 id を持つ work-item からの x の値。

3.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、 T が容易にコピー可能である場合にのみ利用できます。
前提条件: local_id はグループ内のすべての work-item で同一である必要があり、その次元はグループの次元と一致しなければなりません。
戻り値: グループ内で指定された id を持つ work-item からの x の値。

4.17.3.3. group_barriergroup_barrier 関数は、グループバリアを使用してグループ内のすべての work-item を同期します。
1.

template <typename Group>2.

void group_barrier(Group g, memory_scope fence_scope = Group::fence_scope); // (1)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
効果: グループ内のすべての work-item を同期します。現在の work-item は、グループ内のすべての work-item がバリアに到達するまでバリアで待機します。さらに、バリアは mem-fence 操作を実行して、バリアの前に発行されたメモリーアク
セスが、バリアの後に発行されたメモリーアクセスでリオーダーされないようにします。グループ内のすべての work-item
は、バリアで同期する前にフェンスを解放し、その後フェンスを取得します。これらのフェンスの暗黙の同期は、アトミック・
オブジェクトに対する明示的なアトミック操作のように実行されます。
デフォルトでは、これらのフェンスのスコープは、グループ内のすべての work-item を含む最も狭いスコープに設定されます (Group::fence_scope で示されるような)。このスコープは、オプションの fence_scope 引数で指定される広いスコープ
でオーバーライドできます。

第 4 章 SYCL プログラミング・インターフェイス | 367

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

4.17.4. グループ・アルゴリズム・ライブラリー
SYCL は、C++17 仕様のセクション 28 で説明される関数に基づくアルゴリズム・ライブラリーを提供します。それぞれの関数の最初の引数はグループであり、データレンジには multi_ptr クラスのポインター、イテレーター、またはインスタンスを記述できます。このセクションで定義される関数は、sycl 名前空間で使用できるフリー関数です。
これらには標準アルゴリズム・ライブラリーの制限が適用されます。SYCL アルゴリズム・ライブラリーの一部の関数では、デバイス間での移植性を高め、予期しない動作となる可能性を最小限にするため、制限事項が追加されています。
すべてのアルゴリズムは、SYCL でサポートされる基本スカラータイプ (表 183 参照) と、SYCL vec および marray クラスのインスタン
スでサポートされます。
SYCL アルゴリズムへのグループ引数は、指定されたグループ内の work-item が協業して実行する必要があることを示します。すべてのアルゴリズムはグループ関数 (4.17.3 節で定義) として動作し、グループ関数のすべての制限事項を継承します。関数の説明に特に明記されない限り、レンジの要素がグループ内の work-item もどのように処理されるかは未定義です。
SYCL は、グループ内の work-item を使用してイテレーターのレンジに対し操作を実行するアルゴリズムと、グループ内の work-item
によって直接保持されるデータに適用するアルゴリズムに個別の関数を提供します。これらの関数の使用例を以下に示します。
リスト 2. work-group のレデュースにグループ・アルゴリズム・ライブラリーを使用
1.

buffer<int> inputBuf { 1024 };2.

buffer<int> outputBuf { 2 };

3.

{

4.

// 0, 1, 2, 3, ..., 1023 でホスト上のバッファーを初期化

5.

host_accessor a { inputBuf };6.
7.

std::iota(a.begin(), a.end(), 0);
}

8.
9.

myQueue.submit([&](handler& cgh) {

10.
11.

accessor inputValues { inputBuf, cgh, read_only };12.

accessor outputValues { outputBuf, cgh, write_only, no_init };

13.
14.

cgh.parallel_for(nd_range<1>(range<1>(16), range<1>(16)),15.

[=] (nd_item<1> it) {

16.
17.

// イテレーターのレンジで記述される任意数の値にグループ・アルゴリズムを適用します18.

// work-group はすべての inputValues をレデュースし、各 work-item はレンジの一部で機能します19.

int* first = inputValues.get_pointer();

20.

int* last = first + 1024;

21.

int sum = joint_reduce(it.get_group(), first, last, plus<>());

22.

outputValues[0] = sum;

23.
24.

// work-item によって直接保持される値のセットにグループ・アルゴリズムを適用します25.

// work-group はグループのサイズに等しい数の値をレデュースし、各 work-item は 1 つの値を提供します26.

int partial_sum = reduce_over_group(it.get_group(), inputValues[it.get_global_linear_id()], plus<>());

27.

outputValues[1] = partial_sum;

28.
29.
30.

});
});

368 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
31.
32.

assert(outputBuf.get_host_access()[0] == 523776 && outputBuf.get_host_access()[1] == 120);

4.17.4.1. any_of、all_of および none_of
標準 C++ の any_of、all_of および none_of 関数は、ブール条件がレンジ内のいずれかの値、すべての値、または保持されていないことをそれぞれテストします。
SYCL は同様な 2 つのセットのアルゴリズムを提供します。
1.

joint_any_of、joint_all_of および joint_none_of は、グループ内の work-item を使用して対応するアルゴリズムを並列に実行します。

2.

any_of_group、all_of_group および none_of_group は、グループ内の work-item によって直接保持されるデータに適用するブール条件をテストします。

1.

template <typename Group, typename Ptr, typename Predicate>2.

bool joint_any_of(Group g, Ptr first, Ptr last, Predicate pred); // (1)3.
4.

template <typename Group, typename T, typename Predicate>5.

bool any_of_group(Group g, T x, Predicate pred); // (2)6.
7.

template <typename Group>8.

bool any_of_group(Group g, bool pred); // (3)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、Ptr がポインターである場合にのみ利用できます。
前提条件: first と last は、グループ内のすべての work-item で同一である必要があり、pred はグループ内のすべてのwork-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。
戻り値: pred がレンジ [first, last) 内の任意のイテレーターの逆参照の結果に適用されるときに true を返す場合は true。

2.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
前提条件: pred は、グループ内のすべての work-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。
戻り値: pred(x) がグループ内のいずれかの work-item に対して true を返す場合は true。

3.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
戻り値: グループ内のいずれかの work-item に対して pred が true である場合は true。

1.

template <typename Group, typename Ptr, typename Predicate>2.

bool joint_all_of(Group g, Ptr first, Ptr last, Predicate pred); // (1)3.
4.

template <typename Group, typename T, typename Predicate>5.

bool all_of_group(Group g, T x, Predicate pred);// (2)

6.
7.

template <typename Group>8.

bool all_of_group(Group g, bool pred); // (3)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、Ptr がポインターである場合にのみ利用できます。
前提条件: first と last は、グループ内のすべての work-item で同一である必要があり、pred はグループ内のすべてのwork-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。

第 4 章 SYCL プログラミング・インターフェイス | 369

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
戻り値: pred がレンジ [first, last) 内のすべてのイテレーターの逆参照の結果に適用されるときに true を返す場合は true。
2.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
前提条件: pred は、グループ内のすべての work-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。
戻り値: pred(x) がグループ内のすべて work-item に対して true を返す場合は true。

3.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
戻り値: グループ内のすべての work-item に対して pred が true である場合は true。

1.

template <typename Group, typename Ptr, typename Predicate>2.

bool joint_none_of(Group g, Ptr first, Ptr last, Predicate pred); // (1)3.
4.

template <typename Group, typename T, typename Predicate>5.

bool none_of_group(Group g, T x, Predicate pred); // (2)6.
7.

template <typename Group>8.

bool none_of_group(Group g, bool pred); // (3)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、Ptr がポインターである場合にのみ利用できます。
前提条件: first と last は、グループ内のすべての work-item で同一である必要があり、pred はグループ内のすべてのwork-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。
戻り値: pred がレンジ [first, last).内のすべてのイテレーターの逆参照の結果に適用されるときに false を返す場合は true。

2.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
前提条件: pred は、グループ内のすべての work-item で同一タイプと状態を持つ不変呼び出し可能でなければなりません。
戻り値: pred(x) がグループ内のすべて work-item に対して false を返す場合は true。

3.

条件: sycl::is_group_v<std::decay_t<Group>> が true の場合にのみ利用できます。
戻り値: グループ内のすべての work-item に対して pred が false である場合は true。

4.17.4.2. shift_left と shift_right
標準 C++ の shift_left と shift_right 関数は、レンジ内の値をそれぞれ下 (左) または上 (右) に移動します。
SYCL は sub_group クラスと互換性のあるアルゴリズムを提供します。
1.

shift_group_left と shift_group_right は、固定数の work-item を左または右にソフトすることで、グループ内の workitem が保持する値をグループ外の別の work-item に直接移動します。

1.

template <typename Group, typename T>2.

T shift_group_left(Group g, T x, Group::linear_id_type delta = 1); // (1)3.
4.

template <typename Group, typename T>5.

T shift_group_right(Group g, T x, Group::linear_id_type delta = 1); // (2)1.

条件: std::is_same_v<std::decay_t<Group>, sub_group> が true であり、T が容易にコピー可能である場合にのみ利用できます。

370 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
前提条件: グループ内のすべての work-item 間で delta が同一である必要があります。T は自明のコピー可能タイプでな
ければなりません。
戻り値: グループのローカル id (id) が呼び出し元の work-item よりも delta で大きな work-item からの x の値。id + deltaは、グループの線形サイズ以上である可能性がありますが、その場合の戻り値は未指定です。
2.

条件: std::is_same_v<std::decay_t<Group>, sub_group> が true であり、T が容易にコピー可能である場合にのみ利用できます。
前提条件: グループ内のすべての work-item 間で delta が同一である必要があります。T は自明のコピー可能タイプでな
ければなりません。
戻り値: グループのローカル id (id) が呼び出し元の work-item よりも delta で小さな work-item からの x の値。id - deltaは、0 より小さい可能性がありますが、その場合の戻り値は未指定です。

4.17.4.3. permute
SYCL は、sub-group 内の work-item が保持する値を並べ替えるアルゴリズムを提供します。
1.

permute_group_by_xor は、work-item id といくつかの固定マスクのビットごとの XOR (排他的論理和) を計算することで識別される work-item のペアで保持される値を入れ替えることで並べ替えを行います。

1.

template <typename Group, typename T>

2.

T permute_group_by_xor(Group g, T x, Group::linear_id_type mask); // (1)1.

条件: std::is_same_v<std::decay_t<Group>, sub_group> が true であり、T が容易にコピー可能である場合にのみ利用できます。
前提条件: グループ内のすべての work-item 間で mask が同一である必要があります。T は自明のコピー可能タイプでな
ければなりません。
戻り値: グループのローカル id (id) が呼び出し元の work-item のグループのローカル id と mask のビット単位の XOR(排他的論理和) と等しい work-item からの x 値。XOR の結果はグループの線形サイズ以上となる可能性がありますが、その場合戻り値は未指定です。

4.17.4.4. selectSYCL は、sub-group 内の work-item が保持する値を直接交換するアルゴリズムを提供します。
1.

select_from_group によって、work-item はグループ内のほかの work-item が保持する値のコピーを取得できます。

1.

template <typename Group, typename T>2.

T select_from_group(Group g, T x, Group::id_type remote_local_id); // (1)1.

条件: std::is_same_v<std::decay_t<Group>, sub_group> が true であり、T が容易にコピー可能である場合にのみ利用できます。
前提条件: T は自明のコピー可能タイプでなければなりません。
戻り値: remote_local_id で指定されたグループローカル id を持つ work-item からの x の値。remote_local_id の値は、グループ外にある可能性がありますが、この場合戻り値は未指定です。

4.17.4.5. reduce
標準の C++ の reduce 関数は、二項オペレーターによりレンジ内の値を不特定の順番で結合します。

第 4 章 SYCL プログラミング・インターフェイス | 371

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
SYCL は、標準の C++ で定義されるものと同じ一般化された合計値を計算する 2 つの類似したアルゴリズムを提供します。
1.

joint_reduce はグループ内の work-item を使用して、reduce 操作を並列に実行します。

2.

reduce_over_group は、グループ内の work-item が直接保持する値を結合します。

二項オペレーターが可換および結合可能でない場合、これらの関数の呼び出し結果は非決定的です。4.17.2 節で定義される二項オペ
レーターのみが SYCL 2020 の reduce 関数でサポートされます。標準 C++ 構文は、今後の SYCL バージョンとの上位互換のために使用されます。
1.

template <typename Group, typename Ptr, typename BinaryOperation>2.

std::iterator_traits<Ptr>::value_type joint_reduce(Group g, Ptr first, Ptr last, BinaryOperation binary_op); // (1)3.
4.

template <typename Group, typename Ptr, typename T, typename BinaryOperation>

5.

T joint_reduce(Group g, Ptr first, Ptr last, T init, BinaryOperation binary_op); // (2)6.
7.

template <typename Group, typename T, typename BinaryOperation>

8.

T reduce_over_group(Group g, T x, BinaryOperation binary_op); // (3)9.
10.

template <typename Group, typename V, typename T, typename BinaryOperation>

11.

T reduce_over_group(Group g, V x, T init, BinaryOperation binary_op); // (4)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、Ptr が基本タイプへのポインターで、BinaryOperation
が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(*first, *first) は、std::iterator_traits<Ptr>::value_type タイプの値を返す必要があります。
前提条件: first、last および binary_op タイプは、グループ内のすべての work-item で同一である必要があります。
binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: オペレーター binary_op を使用して、レンジ [first, last) 内のすべてのイテレーターを逆参照した結果を結合した
値を返します。値は、標準 C++ で定義され一般化された sum に従って結合されます。

2.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、Ptr が基本タイプへのポインターで、T が基本タイプ、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(init, *first) は T タイプの値をリターンする必要があります。
前提条件: first、last、init および binary_op のタイプは、グループ内のすべての work-item で同一である必要があります。
binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: オペレーター binary_op を使用して、レンジ [first, last) 内のすべてのイテレーターを逆参照した結果の値と初期値 init を結合した値を返します。値は、標準 C++ で定義され一般化された sum に従って結合されます。

3.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、T が基本タイプで、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(x, x) は T タイプの値をリターンする必要があります。
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: オペレーター binary_op を使用して、グループ内の各 work-item によって指定される x のすべての値を結合した
結果を返します。値は、標準 C++ で定義され一般化された sum に従って結合されます。

4.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、V と X が基本タイプで、BinaryOperation が SYCL 関数
オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(init, x) は T タイプの値をリターンする必要があります。

372 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: オペレーター binary_op を使用して、グループ内の各 work-item によって指定される x のすべての値と初期値 initを結合した値を返します。値は、標準 C++ で定義され一般化された sum に従って結合されます。

4.17.4.6. exclusive_scan と inclusive_scan
標準 C++ の exclusive_scan と inclusive_scan 関数は、二項オペレーターを使用してプリフィクス sum を計算します。要素 [x0, …,

xn] のスキャンでは、排他スキャンの i 番目の結果は xi に先行するすべての要素 (xi 自身を除く) の一般化された非可換 sum ですが、包括スキャンの i 番目の結果は一般化された非可換 xi に先行するすべての要素の sum です (xi 自身を含む)。
SYCL は、標準の C++ で定義される一般化された非可換 sum を使用して同じプリフィクス sum を計算する 2 つの類似したアルゴリ
ズムを提供します。
1.

joint_exclusive_scan と joint_inclusive_scan は、グループ内の work-item を使用して対応するアルゴリズムを並列に実行し、中間の部分プリフィクス sum は標準 C++ のようにメモリーに書き込まれます。

2.

exclusive_scan_over_group と inclusive_scan_over_group は、グループ内の work-item によって直接保持される値に対しスキャンを実行し、各 work-item に返される結果は部分プリフィクス sum を表します。

二項オペレーターが結合可能でない場合、スキャンの呼び出し結果は非決定的です。4.17.2 節で定義される二項オペレーターのみが
SYCL 2020 のスキャン関数でサポートされます。標準 C++ 構文は今後の SYCL バージョンとの上位互換のために使用されます。
1.

template <typename Group, typename InPtr, typename OutPtr, typename BinaryOperation>

2.

OutPtr joint_exclusive_scan(Group g, InPtr first, InPtr last, OutPtr result, BinaryOperation binary_op); // (1)3.
4.

template <typename Group, typename InPtr, typename OutPtr, typename T, typename BinaryOperation>

5.

OutPtr joint_exclusive_scan(Group g, InPtr first, InPtr last, OutPtr result, T init, BinaryOperation binary_op); //
(2)

6.
7.

template <typename Group, typename T, typename BinaryOperation>

8.

T exclusive_scan_over_group(Group g, T x, BinaryOperation binary_op); // (3)9.
10.

template <typename Group, typename V, typename T, typename BinaryOperation>11.

T exclusive_scan_over_group(Group g, V x, T init, BinaryOperation binary_op); // (4)1.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、InPtr と OutPtr が基本タイプへのポインターで、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(*first, *first) は、std::iterator_traits<OutPtr>::value_type タイプの値を返す必要があります。
前提条件: first、last、result および binary_op のタイプは、グループ内のすべての work-item で同一である必要があります。binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。

first が result と等しいことがあることに注意してください。

効果: result + i に書き込まれる値は、オペレーター binary_op を使用して、レンジ [first, last) の最初の i 値とbinary_op (sycl::known_identity で識別される) の単位元の値を逆参照した結果の排他的スキャンの結果です。スキャ
ンは標準 C++ で定義される一般化された非可換 sum によって計算されます。
戻り値: 出力レンジの最後へのポインターを返します。
2.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、InPtr と OutPtr が基本タイプへのポインターであり、Tが基本タイプで、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。

第 4 章 SYCL プログラミング・インターフェイス | 373

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
必須: binary_op(init, *first) は T タイプの値をリターンする必要があります。
前提条件: first、last、result、init および binary_op のタイプは、グループ内のすべての work-item で同一である必要があります。binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。

first が result と等しいことがあることに注意してください。

効果: result + i に書き込まれる値は、オペレーター binary_op を使用して、レンジ [first, last) の最初の i 値と init によって指定される初期値を逆参照した結果の排他的スキャンの結果です。スキャンは標準 C++ で定義される一般化された非可換 sum によって計算されます。
戻り値: 出力レンジの最後へのポインターを返します。
3.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、T が基本タイプで、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(x, x) は T タイプの値をリターンする必要があります。
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: work-item i に返される値は、オペレーター binary_op を使用して、グループ内の最初の i 値と binary_op(sycl::known_identity で識別される) の単位元の値を逆参照した結果の値の排他的スキャンの結果です。スキャンは標準
C++ で定義される一般化された非可換 sum によって計算されます。多次元グループの場合、グループ内の work-item の
順番は線形 id によって決定されます。

4.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、V と T が基本タイプで、BinaryOperation が SYCL 関数
オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(init, x) は T タイプの値をリターンする必要があります。
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: work-item i に返される値は、グループ内の最初の i 値の排他的スキャンと、binary_op オペレーターを使用してinit で指定される初期値です。スキャンは標準 C++ で定義される一般化された非可換 sum によって計算されます。多次元
グループの場合、グループ内の work-item の順番は線形 id によって決定されます。

1.

template <typename Group, typename InPtr, typename OutPtr, typename BinaryOperation>

2.

OutPtr joint_inclusive_scan(Group g, InPtr first, InPtr last, OutPtr result, BinaryOperation binary_op); // (1)3.
4.

template <typename Group, typename InPtr, typename OutPtr, typename T, typename BinaryOperation>

5.

OutPtr joint_inclusive_scan(Group g, InPtr first, InPtr last, OutPtr result, BinaryOperation binary_op, T init); //
(2)

6.
7.

template <typename Group, typename T, typename BinaryOperation>

8.

T inclusive_scan_over_group(Group g, T x, BinaryOperation binary_op); // (3)9.
10.

template <typename Group, typename V, typename T, typename BinaryOperation>

11.

T inclusive_scan_over_group(Group g, V x, BinaryOperation binary_op, T init); // (4)1.

条 件 : sycl::is_group_v<std::decay_t<Group>> が true で 、 InPtr と OutPtr が 基 本 タ イ プ の ポ イ ン タ ー で あ り 、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(*first, *first) は、std::iterator_traits<OutPtr>::value_type タイプの値を返す必要があります。
前提条件: first、last、result および binary_op のタイプは、グループ内のすべての work-item で同一である必要があります。binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。

374 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

first が result と等しいことがあることに注意してください。

効果: result + i に書き込まれる値は、オペレーター binary_op を使用して、レンジ [first, last) の最初の i 値と binary_opの単位元の値を逆参照した結果の包括的スキャンの結果です。スキャンは標準 C++ で定義される一般化された非可換
sum によって計算されます。
戻り値: 出力レンジの最後へのポインターを返します。
2.

条件: sycl::is_group_v<std::decay_t<Group>> が true で、InPtr と OutPtr が基本タイプへのポインターであり、BinaryOperation が SYCL 関数オブジェクト・タイプで、T が基本タイプである場合にのみ利用できます。
必須: binary_op(init, *first) は T タイプの値をリターンする必要があります。
前提条件: first、last、result、init および binary_op のタイプは、グループ内のすべての work-item で同一である必要があります。binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。

first が result と等しいことがあることに注意してください。

効果: result + i に書き込まれる値は、オペレーター binary_op を使用して、レンジ [first, last) の最初の i 値と init によって指定される初期値を逆参照した結果の包括的スキャンの結果です。スキャンは標準 C++ で定義される一般化された非可換 sum によって計算されます。
戻り値: 出力レンジの最後へのポインターを返します。
3.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、T が基本タイプで、BinaryOperation が SYCL 関数オブジェクト・タイプである場合にのみ利用できます。
必須: binary_op(x, x) は T タイプの値をリターンする必要があります。
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: work-item i に返される値は、binary_op オペレーターを使用して、グループ内の最初の i 値を包括的スキャンした結果です。スキャンは標準 C++ で定義される一般化された非可換 sum によって計算されます。多次元グループの場合、グループ内の work-item の順番は線形 id によって決定されます。

4.

条件: sycl::is_group_v<std::decay_t<Group>> が true であり、V が基本タイプで、BinaryOperation が SYCL 関数オブジェクト・タイプであり、T が基本タイプの場合にのみ利用できます。
必須: binary_op(init, x) は T タイプの値をリターンする必要があります。
前提条件: binary_op は SYCL 関数オブジェクトのインスタンスでなければなりません。
戻り値: work-item i に返される値は、binary_op オペレーターを使用して、グループ内の最初の i 値と init で指定される初期値を包括的スキャンした結果です。スキャンは標準 C++ で定義される一般化された非可換 sum によって計算されます。
多次元グループの場合、グループ内の work-item の順番は線形 id によって決定されます。

4.17.5. 数学関数
SYCL では、ホストとデバイスで sycl 名前空間と『OpenCL 1.2 仕様』の 7 章で定義される精度で OpenCL 数学関数を利用できます。
SYCL プラットフォームでは、ホストの数値要件は OpenCL 数学ビルトイン関数の数値要件と一致する必要があります。ビルトイン関数は、次元 1 を含むサポートされるすべての次元において、入力として float (またはオプションで double)、およびそれらの vec およびmarray を受け入れることができます。

第 4 章 SYCL プログラミング・インターフェイス | 375

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
ホストとデバイスの両方で同じ精度の SYCL ホストとデバイスで利用できるビルトイン関数については、表 175 で説明します。
表 175. SYCL ホストとデバイスで動作する数学関数。これらは、『OpenCL 1.2 仕様』の表 6.8 に対応しています。
数学関数

説明

genfloat acos (genfloat x)逆余弦関数。

genfloat acosh (genfloat x)

逆双曲線余弦。

genfloat acospi (genfloat x)を計算

genfloat asin (genfloat x)逆正弦関数。

genfloat asinh (genfloat x)

逆双曲線正弦。

genfloat asinpi (genfloat x)
genfloat atan (genfloat y_over_x)
genfloat atan2 (genfloat y, genfloat x)
genfloat atanh (genfloat x)
genfloat atanpi (genfloat x)
genfloat atan2pi (genfloat y, genfloat x)を計算します。
逆正接関数。
を計算します。
双曲線逆正接。
を計算します。
を計算します。

genfloat cbrt (genfloat x)

立方根を計算。

genfloat ceil (genfloat x)

正の無限大への丸めモードで整数値に丸めます。

genfloat copysign (genfloat x, genfloat y)x の符号を y の符号に変更します。

genfloat cos (genfloat x)余弦を計算します。

genfloat cosh (genfloat x)

双曲線余弦を計算します。

genfloat cospi (genfloat x)を計算します。

genfloat erfc (genfloat x)

誤差関数の値を補完します。

genfloat erf (genfloat x)

正規分布の積分中のエラー関数。

genfloat exp (genfloat x)

基数 e の指数を計算します。

genfloat exp2 (genfloat x)

基数 2 の指数を計算します。

genfloat exp10 (genfloat x)

基数 10 の指数を計算します。

genfloat expm1 (genfloat x)を計算します。

genfloat fabs (genfloat x)

浮動小数点の絶対値を計算します。

genfloat fdim (genfloat x, genfloat y)

x > y の場合は x - y、x が y 以下の場合は +0。

genfloat floor (genfloat x)

負の無限大への丸めモードを使用して整数値に丸めます。

376 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

数学関数

説明

genfloat fma (genfloat a, genfloat b, genfloat c)a と b の総乗と c の和を正しく丸めた浮動小数点表現を返します。
中間結果の丸めは行われません。エッジケースの動作は IEEE
754-2008 規格に準拠します。

genfloat fmax (genfloat x, genfloat y)

x < y の場合 y を返し、それ以外は x を返します。引数の 1 つがgenfloat fmax (genfloat x, sgenfloat y)

NaN である場合、fmax() はもう一方の引数を返します。両方の引数が NaN である場合、fmax() は NaN を返します。

genfloat fmin (genfloat x, genfloat y)y < x の場合 y を返し、それ以外は x を返します。引数の 1 つがgenfloat fmin (genfloat x, sgenfloat y)

NaN である場合、fmin() はもう一方の引数を返します。両方の引数が NaN である場合、fmin() は NaN を返します。

genfloat fmod (genfloat x, genfloat y)係数。x mod y・trunc(x/y) を返します。

genfloat fract (genfloat x, genfloatptr iptr)

fmin(x - floor(x), nextafter(genfloat(1.0), genfloat(0.0))) を返します。floor(x) は iptr に返されます。

genfloat frexp (genfloat x, genintptr exp)

x から仮数と指数を抽出します。コンポーネントごとに返される値
は、区間 [1/2, 1) または 0 の絶対値を持つ浮動小数点です。x の各コンポーネントは、返された係数 x 2exp に等しくなります。

genfloat hypot (genfloat x, genfloat y)

オーバーフローまたはアンダーフローなしで x2 + y2 の平方根を計算します。

genint ilogb (genfloat x)

logr (|x|) の整数部分を計算して整数の結果を返します。ここで、rは std::numeric_limits<genfloat>::radix が返す値です。

genfloat ldexp (genfloat x, genint k)

x に 2k を掛けます。

genfloat ldexp (genfloat x, int k)genfloat lgamma (genfloat x)

対数ガンマ関数。ガンマ関数の絶対値の自然対数を返します。

genfloat lgamma_r (genfloat x, genintptr signp)

対数カンマ関数。ガンマ関数の絶対値の自然対数を返します。ガンマ関数の符号は、lgamma_r の signp 引数に返されます。

genfloat log (genfloat x)

自然対数を計算します。

genfloat log2 (genfloat x)

基数 2 の対数を計算します。

genfloat log10 (genfloat x)

基数 10 の対数を計算します。

genfloat log1p (genfloat x)loge(1.0 + x) を計算します。

genfloat logb (genfloat x)

logr (|x|) の整数部分を計算します。ここで、r は
std::numeric_limits<genfloat>::radix が返す値です。

genfloat mad (genfloat a,genfloat b, genfloat c)

mad は a * b + c を近似します。a * b の積を丸めるか、またはどのように丸めるか、および超常積または非正規中間積がどのように扱われるかは定義されていません。mad は精度よりもスピードが優先される場合の使用を目的としています。

genfloat maxmag (genfloat x, genfloat y)|x| > |y| の場合は x を返し、|y| > |x| の場合は y を返します。それ以外は fmax(x, y) を返します。

第 4 章 SYCL プログラミング・インターフェイス | 377

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

数学関数

説明

genfloat minmag (genfloat x, genfloat y)|x| < |y| の場合は x を返し、|y| < |x| の場合は y を返します。それ以外は fmin(x, y) を返します。

genfloat modf (genfloat x, genfloatptr iptr)

浮動小数点数を分解します。modf 関数は、引数 x を整数部と小数部に分割します。各部分は、引数と同じ符号を持ちます。iptr で指定されるオブジェクトに積分を格納します。

genfloatf nan (ugenint nancode)

QNaN を返します。結果の NaN の仮数部に nancode を配置しま

genfloatd nan (ugenlonginteger nancode)す。

genfloat nextafter (genfloat x, genfloat y)

y 方向に x の次に表現可能な単精度浮動小数点値を計算します。
y が x よりも小さい場合、nextafter() は x よりも小さい最大の表
現可能な浮動小数点数を返します。

genfloat pow (genfloat x, genfloat y)

x の y 乗を計算します。

genfloat pown (genfloat x, genint y)

x の y 乗を計算します (y は整数)。

genfloat powr (genfloat x, genfloat y)

x の y 乗を計算します (x ≥ 0)。

genfloat remainder (genfloat x, genfloat y)r = x - n * y となるような r 値を計算します。ここで、n は x/y の正確な値に最も近い整数です。x/y に最も近い整数が 2 つ存在する
場合、n は偶数になります。r がゼロである場合、x と同じ符号が適用されます。

genfloat remquo (genfloat x, genfloat y, genintptr quo)

remquo 関数は、r = x - k * y となる r 値を計算します。ここで、kは x/y の正確な値に最も近い整数です。x/y に最も近い整数が 2つ存在する場合、k は偶数になります。r がゼロである場合、x と同じ符号が適用されます。これは remainder 関数によって返される値と同じです。remquo 関数は、積分商 x/y の下位 7 ビットを計算し、その値に x/y と同じ符号を適用します。この符号付きの値をquo で指定されるオブジェクトに格納します。

genfloat rint (genfloat x)

浮動小数点形式で整数値に丸めます (最も近い偶数への丸めモードを使用)。丸めモードについては、『OpenCL 1.2 仕様』の7.1 節を参照してください。

genfloat rootn (genfloat x, genint y)

x の 1/y 乗を計算します。

genfloat round (genfloat x)

現在の丸め方向にかかわりなく、0 から離れた x の丸めの半分に最も近い整数値を返します。

genfloat rsqrt (genfloat x)

逆平方根を計算します。

genfloat sin (genfloat x)正弦を計算します。

genfloat sincos (genfloat x, genfloatptr cosval)

x の正弦と余弦を計算します。計算された正弦が戻り値であり、余弦が cosval に返されます。

genfloat sinh (genfloat x)

双曲線正弦を計算します。

genfloat sinpi (genfloat x)sin(π x) を計算します。

378 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

数学関数

説明

genfloat sqrt (genfloat x)

平方根を計算します。

genfloat tan (genfloat x)正接を計算します。

genfloat tanh (genfloat x)

双曲線正接を計算します。

genfloat tanpi (genfloat x)tan(π x) を計算します。

genfloat trunc (genfloat x)

ゼロへの丸めモードで整数値に丸めます。

SYCL では、実装依存の精度の数学関数は sycl::native 名前空間で定義されます。この名前空間で使用できる関数は、表 176 に示します。
表 176. ネイティブの数学関数
ネイティブ算術関数

説明

genfloatf cos (genfloatf x)実装で定義されたレンジで余弦を計算します。最大値エラーは実装定義です。

genfloatf divide (genfloatf x, genfloatf y)

実装定義のレンジで x/y を計算します。最大値エラーは実装定義です。

genfloatf exp (genfloatf x)実装で定義されたレンジで x の基数 e の指数を計算します。最大
値エラーは実装定義です。

genfloatf exp2 (genfloatf x)実装で定義されたレンジで x の基数2 の指数を計算します。最大
値エラーは実装定義です。

genfloatf exp10 (genfloatf x)実装で定義されたレンジで x の基数10 の指数を計算します。最大値エラーは実装定義です。

genfloatf log (genfloatf x)実装で定義されたレンジで自然対数を計算します。最大値エラー
は実装定義です。

genfloatf log2 (genfloatf x)実装で定義されたレンジで基数 2 の対数を計算します。最大値エラーは実装定義です。

genfloatf log10 (genfloatf x)実装で定義されたレンジで基数10 の対数を計算します。最大値
エラーは実装定義です。

genfloatf powr (genfloatf x, genfloatf y)

x の y 乗を計算します (x ≥ 0)。
x と y のレンジは実装定義です。最大値エラーは実装定義です。

genfloatf recip (genfloatf x)実装で定義されたレンジで逆数を計算します。最大値エラーは実装定義です。

genfloatf rsqrt (genfloatf x)実装で定義されたレンジで逆平方根を計算します。最大値エラー
は実装定義です。

genfloatf sin (genfloatf x)実装で定義されたレンジで正弦を計算します。最大値エラーは実装定義です。

第 4 章 SYCL プログラミング・インターフェイス | 379

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

ネイティブ算術関数

説明

genfloatf sqrt (genfloatf x)実装で定義されたレンジで平方根を計算します。最大値エラーは実装定義です。

genfloatf tan (genfloatf x)実装で定義されたレンジで正接を計算します。最大値エラーは実装定義です。

SYCL では、半精度の数学関数は sycl::half_precision で定義されます。この名前空間で使用できる関数は、表 177 に示します。これ
らの関数は最小 10 ビットの精度で実装されます。最大エラーは 8192ulp 以下です。
表 177. 半精度算術関数
半精度算術関数説明

genfloatf cos (genfloatf x)余弦を計算します。x は、-216 ～ +216 の範囲になければなりません。

genfloatf divide (genfloatf x, genfloatf y)

x/y を計算します。

genfloatf exp (genfloatf x)x の基数 e の指数を計算します。

genfloatf exp2 (genfloatf x)x の基数 2の指数を計算します。

genfloatf exp10 (genfloatf x)x の基数 10 の指数を計算します。

genfloatf log (genfloatf x)

自然対数を計算します。

genfloatf log2 (genfloatf x)

基数 2 の対数を計算します。

genfloatf log10 (genfloatf x)

基数 10 の対数を計算します。

genfloatf powr (genfloatf x, genfloatf y)

x の y 乗を計算します (x ≥ 0)。

genfloatf recip (genfloatf x)

逆数を計算します。

genfloatf rsqrt (genfloatf x)

逆平方根を計算します。

genfloatf sin (genfloatf x)正弦を計算します。x は、-216 ～ +216 の範囲になければなりません。

genfloatf sqrt (genfloatf x)

平方根を計算します。

genfloatf tan (genfloatf x)正接を計算します。x は、-216 ～ +216 の範囲になければなりません。

4.17.6. 整数関数
整数数学関数は、ホストとデバイスの sycl 名前空間で使用できます。ビルトイン関数は、入力として char、unsigned char、short、
unsigned short、int、unsigned int、long long int、unsigned long long int およびそれらの vec と marray を受け入れます。サポー
トされる整数数学関数を表 178 に示します。

380 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
表 178. sycl 名前空間で使用できる SYCL ホストおよびデバイスで動作する整数数学関数
整数関数

説明

geninteger abs (geninteger x)|x| を返します。

ugeninteger abs_diff (geninteger x, geninteger y)

モジュロ・オーバーフローなしで |x - y| を返します。

geninteger add_sat (geninteger x, geninteger y)

x + y を返し、結果を飽和させます。

geninteger hadd (geninteger x, geninteger y)(x + y) >> 1 を返します。中間 sum はモジュロ・オーバーフローしません。

geninteger hadd (geninteger x, geninteger y)(x + y + 1) >> 1 を返します。中間 sum はモジュロ・オーバーフ
ローしません。

geninteger clamp (geninteger x, geninteger minval,min(max(x, minval), maxval) を返します。minval > maxval のgeninteger maxval)

場合結果は未定義です。

geninteger clamp (geninteger x, sgeninteger minval,sgeninteger maxval)
geninteger clz (geninteger x)

最上位ビット位置から始まる x の先行 0 ビットの数を返します。xが 0 の場合、x のタイプやコンポーネントのタイプ (x がベクトルの場合) のサイズをビット単位で返します。

geninteger ctz (geninteger x)

x のトレール 0 ビットの数を返します。x が 0 の場合、x のタイプまたは x のコンポーネントのタイプ (x がベクトルの場合) のサイズ
をビット単位で返します。

geninteger mad_hi (mul_hi(a, b)+c を返します。

geninteger a, geninteger b, geninteger c)geninteger mad_sat (a * b + c の飽和を返します。

geninteger a, geninteger b, geninteger c)geninteger hadd (geninteger x, geninteger y)

x < y の場合 y を返し、それ以外は x を返します。

geninteger max (geninteger x, sgeninteger y)geninteger min (geninteger x, geninteger y)y < x の場合 y を返し、それ以外は x を返します。

geninteger min (geninteger x, sgeninteger y)geninteger mul_hi (geninteger x, geninteger y)

x * y を計算し、x と y の積の上位半分を返します。

geninteger rotate (geninteger v, geninteger i)

v の各要素において、ビットは i の対応する要素で指定されたビッ
ト数だけ左シフトされます (『OpenCL 1.2 仕様』の 6.3 節で説明されている通常のシフトモジュロ規則に従います)。要素の左から
シフトアウトされたビットは、右側からシフトインされます。

geninteger sub_sat (geninteger x, geninteger y)

x - y の結果を飽和させます。

ugeninteger16bit upsample (ugeninteger8bit hi,

result[i] = ((ushort)hi[i] << 8) | lo[i]ugeninteger8bit lo)
igeninteger16bit upsample (igeninteger8bit hi,

result[i] = ((short)hi[i] << 8) | lo[i]ugeninteger8bit lo)

第 4 章 SYCL プログラミング・インターフェイス | 381

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

整数関数

説明

ugeninteger32bit upsample (ugeninteger16bit hi,

result[i] = ((uint)hi[i] << 16) | lo[i]ugeninteger16bit lo)
igeninteger32bit upsample (igeninteger16bit hi,

result[i] = ((int)hi[i] << 16) | lo[i]ugeninteger16bit lo)
ugeninteger64bit upsample (ugeninteger32bit hi,

result[i] = ((ulonglong)hi[i] << 32) | lo[i]ugeninteger32bit lo)
igeninteger64bit upsample (igeninteger32bit hi,

result[i] = ((longlong)hi[i] << 32) | lo[i]ugeninteger32bit lo)
geninteger popcount (geninteger x)

x の非ゼロビットの数を返します。

geninteger32bit mad24 (geninteger32bit x,

24 ビット整数値 x と y を乗算し、32 ビット整数の結果を 32 ビッ

geninteger32bit y, geninteger32bit z)

ト整数 z に加算します。24 ビット整数の乗算がどのように実行されるかは、mul24 の定義を参照してください。

geninteger32bit mul24 (geninteger32bit x,

24 ビット整数値 x と y を乗算します。x と y は 32 ビット整数でgeninteger32bit y)

す が、乗 算の 実行 には 下位 24 ビットの み が使 用さ れ ます。
mul24 は、x と y の値が [-223, 223 -1] のレンジにあり、x と y が符号付き整数で[0, 224 - 1] レンジにある場合にのみ使用する必要があります。
x と y がこのレンジ内にない場合、乗算の結果は実装定義です。

4.17.7. 共通関数
SYCL では、OpenCL 共通関数は、『OpenCL 1.2 仕様』の 6.12.4 節で定義されているように、ホストとデバイスの sycl 名前空間で利用できます。詳細を表 179 に示します。ビルトイン関数は入力として float (またはオプションで double)、およびそれらの vec またはmarray を受け入れることができます。
表 179. sycl 名前空間で使用できる SYCL ホストおよびデバイスで動作する共通関数。これらは、『OpenCL 1.2 仕様』の表 6.12に対応しています。
共通関数

説明

genfloat clamp (genfloat x, genfloat minval, genfloat

fmin(fmax(x, minval), maxval) を返します。minval > maxval のmaxval)場合、結果は未定義です。

genfloatf clamp (genfloatf x, float minval, float maxval)
genfloatd clamp (genfloatd x, double minval, double
maxval)genfloat degrees (genfloat radians)

ラジアンを度に変換します。
例えば、180/π x radians。

genfloat max (genfloat x, genfloat y)

x < y の場合 y を返し、それ以外は x を返します。x または y が無genfloatf max (genfloatf x, float y)

限大もしくは NaN の場合、戻り値は未定義です。

genfloatd max (genfloatd x, double y)382 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

共通関数

説明

genfloat min (genfloat x, genfloat y)y < x の場合 y を返し、それ以外は x を返します。x または y が無genfloatf min (genfloatf x, float y)

限大もしくは NaN の場合、戻り値は未定義です。

genfloatd min (genfloatd x, double y)
genfloat mix (genfloat x, genfloat y, genfloat a)

次のように実装された x と y の線形ブレンドを返します。

genfloatf mix (genfloatf x, genfloatf y, float a)x + ( y - x) x a

genfloatd mix (genfloatd x, genfloatd y, double a)a は 0.0 .. 1.0 の間の値でなければなりません。
a が 0.0 .. 1.0 のレンジにない場合、戻り値は未定義です。

genfloat radians (genfloat degrees)

degrees を radians に変換します。例: (π / 180) x degrees。

genfloat step (genfloat edge, genfloat x)

x < edge の場合 0.0 を返し、それ以外は 1.0 を返します。

genfloatf step (float edge, genfloatf x)
genfloatd step (double edge, genfloatd x)
genfloat smoothstep (genfloat edge0, genfloat edge1,x ≤ edge0 の場合 0.0 を返し、x ≥ edge1 の場合 1.0 を返し、

genfloat x)

edge0 < x < edge1 の場合はスムーズエルミート補間を行いgenfloatf smoothstep (float edge0, float edge1, genfloatf

ます。

x)
genfloatd smoothstep (double edge0, double edge1,
genfloatd x)

これは、スムーズな遷移を伴うしきい値関数が必要である場合に役立ちます。
これは以下と等価です。
gentype t;t = clamp ((x <= edge0) / (edge1 >= edge0), 0, 1);
return t * t * (3 - 2 * t);edge0 >= edge1 または x、edge0、edge1 が NaN の場合結果は未定義です。

genfloat sign (genfloat x)

x > 0 の場合 1.0 を、x = -0.0 の場合は -0.0 を、x = +0.0 の場合
は +0.0、および x < 0 の場合は -1.0 を返します。x が NaN の場
合は 0.0 を返します。

4.17.8. ジオメトリー関数
SYCL では、OpenCL ジオメトリー関数は、『OpenCL 1.2 仕様』の 6.12.5 節で定義されているように、ホストとデバイスの sycl 名前空間で利用できます。ビルトイン関数は入力として float (またはオプションで double)、およびそれらの 2、3、および 4 次元の vec またはmarray を受け入れることができます。ホストでは、ベクトルタイプは vec クラスを使用して SYCL デバイスで対応する SYCL バックエ
ンドのベクトルタイプを使用します。すべてのジオメトリー関数は、最も近い偶数への丸めモードを使用します。表 180 にサポートされるジオメトリー関数の定義が含まれます。

第 4 章 SYCL プログラミング・インターフェイス | 383

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数
表 180. sycl 名前空間で使用できる SYCL ホストおよびデバイスで動作するジオメトリー関数。これらは、『OpenCL 1.2 仕様』の表
6.13 に対応しています。
ジオメトリー関数

説明

float4 cross (float4 p0, float4 p1)

p0.xyz と p1.xyz の外積を返します。返される float4 の結果の w

float3 cross (float3 p0, float3 p1)

成分は 0.0 になります。

double4 cross (double4 p0, double4 p1)
double3 cross (double3 p0, double3 p1)
mfloat4 cross (mfloat4 p0, mfloat4 p1)

p0 と p1 の最初の 3 つの成分の外積を返します。返される結果のmfloat3 cross (mfloat3 p0, mfloat3 p1)

4番目の成分は 0.0 になります。

mdouble4 cross (mdouble4 p0, mdouble4 p1)
mdouble3 cross (mdouble3 p0, mdouble3 p1)
float dot (gengeofloat p0, gengeofloat p1)

内積を計算します。

double dot (gengeodouble p0, gengeodouble p1)
float distance (gengeofloat p0, gengeofloat p1)

p0 と p1 の距離を返します。これは、length(p0 - p1) として計算

double distance (gengeodouble p0, gengeodouble p1)

されます。

float length (gengeofloat p)

ベクトル p のレングスを返します。

double length (gengeodouble p)gengeofloat normalize (gengeofloat p)√𝑝. 𝑥 2 + 𝑝. 𝑦 2 + ⋯p と同じ方向でレングス 1 のベクトルを返します。

gengeodouble normalize (gengeodouble p)
float fast_distance (gengeofloat p0, gengeofloat p1)

fast_length(p0 - p1) を返します。

float fast_length (gengeofloat p)

次のように計算されるベクトル p のレングスを返します。
sqrt((half)) (pow(p.x,2) + pow(p.y,2) + ...))

gengeofloat fast_normalize (gengeofloat p)

p と同じ方向でレングス 1 のベクトルを返します。fast_normalizeは次のように計算されます。
p*rsqrt((half)) (pow(p.x,2) + pow(p.y,2) + ...))
結果は、次の無限の精度の結果から 8192 ulps 以内の誤差でなければなりません。
if (all(p == 0.0f))
result = p;
else
result = p/sqrt (pow(p.x,2) + pow(p.y,2) + ...);
ただし、次の例外を除きます。
1.

二乗和が FLT_MAX より大きい場合、結果ベクトル
内の浮動小数点値は未定義です。

2.

平方和が FLT_MIN 未満である場合、実装は p を返すことがあります。

3.

デバイスが「デノーマルをゼロにフラッシュ」モードである場合、sqrt(FLT_MIN) より小さな値のそれぞれのオペランド要素は、計算を続行する前にゼロにフラッ
シュすることができます。

384 | 第 4 章 SYCL プログラミング・インターフェイスSYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

4.17.9. リレーショナル関数
フォローフリー関数は、sycl 名前空間で定義されており、ホストとデバイスの両方で利用できます。 これらの関数は、vec、marray およびスカラータイプに対し、さまざまなリレーショナル比較操作を実行します。
一方または両方のオペランドが NaN である場合、isequal、isgreater、isgreaterequal、isless、islessequal および islessgreater による比較結果は false になります。 また、一方または両方のオペランドが NaN である場合、isnotequal による比較は true になります。.
これらの関数の vec バージョンは、『OpenCL 1.2 仕様』の 6.12.6 節の定義に従います。特に指定されない限り、これらの関数は比較が true の場合は -1 (すべてのビットが設定されている) のベクトル・コンポーネントを返し、false の場合は 0 を返します。
vec タイプで利用可能な関数を表 181 に示します。
表 181. vec テンプレート・クラスのリレーショナル関数
リレーショナル関数

説明

vec<int16_t,{n}> isequal (half{n} x, half{n} y)x == y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> isequal (float{n} x, float{n} y)vec<int64_t,{n}> isequal (double{n} x, double{n} y)vec<int16_t,{n}> isnotequal (half{n} x, half{n} y)x != y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> isnotequal (float{n} x, float{n} y)vec<int64_t,{n}> isnotequal (double{n} x, double{n} y)vec<int16_t,{n}> isgreater (half{n} x, half{n} y)x > y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> isgreater (float{n} x, float{n} y)vec<int64_t,{n}> isgreater (double{n} x, double{n} y)vec<int16_t,{n}> isgreaterequal (half{n} x, half{n} y)x >= y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> isgreaterequal (float{n} x, float{n} y)vec<int64_t,{n}> isgreaterequal (double{n} x, double{n} y)vec<int16_t,{n}> isless (half{n} x, half{n} y)x < y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> isless (float{n} x, float{n} y)vec<int64_t,{n}> isless (double{n} x, double{n} y)vec<int16_t,{n}> islessequal (half{n} x, half{n} y)x <= y のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> islessequal (float{n} x, float{n} y)vec<int64_t,{n}> islessequal (double{n} x, double{n} y)vec<int16_t,{n}> islessgreater (half{n} x, half{n} y)(x < y) || (x >y) のコンポーネントごとの比較結果を返します。

vec<int32_t,{n}> islessgreater (float{n} x, float{n} y)vec<int64_t,{n}> islessgreater (double{n} x, double{n} y)vec<int16_t,{n}> isfinite (half{n} x)

有限値をテストします。

vec<int32_t,{n}> isfinite (float{n} x)vec<int64_t,{n}> isfinite (double{n} x)vec<int16_t,{n}> isinf (half{n} x)

無限大値 (正または負) をテストします。

vec<int32_t,{n}> isinf (float{n} x)vec<int64_t,{n}> isinf (double{n} x)

第 4 章 SYCL プログラミング・インターフェイス | 385

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

リレーショナル関数

説明

vec<int16_t,{n}> isnan (half{n} x)

NaN をテストします。

vec<int32_t,{n}> isnan (float{n} x)vec<int64_t,{n}> isnan (double{n} x)vec<int16_t,{n}> isnormal (half{n} x)

正常値をテストします。

vec<int32_t,{n}> isnormal (float{n} x)vec<int64_t,{n}> isnormal (double{n} x)vec<int16_t,{n}> isordered (half{n} x, half{n} y)

引数が順序付けられているかテストします。isordered() は、引数

vec<int32_t,{n}> isordered (float{n} x, float{n} y)x と y を受け取り、isequal(x, y) && isequal(y, y) の結果を返しま

vec<int64_t,{n}> isordered (double{n} x, double{n} y)す。

vec<int16_t,{n}> isunordered (half{n} x, half{n} y)

引数が順序付けられてないかテストします。isunordered() は、引

vec<int32_t,{n}> isunordered (float{n} x, float{n} y)数 x と y を受け取り、x または y が NaN である場合は非ゼロを返

vec<int64_t,{n}> isunordered (double{n} x, double{n} y)

し、それ以外はゼロを返します。

vec<int16_t,{n}> signbit (half{n} x)

符号ビットをテストします。x の各コンポーネントに対して、コン

vec<int32_t,{n}> signbit (float{n} x)

ポーネント値の符号ビットが設定されている場合は -1 (すべてのvec<int64_t,{n}> signbit (double{n} x)ビットが設定されている) を返し、それ以外は 0 を返します。

int any (vigeninteger x)

x のいずれかのコンポーネントの最上位ビットが設定されている
場合は 1 を返し、それ以外は 0 を返します。

int all (vigeninteger x)

x のすべてのコンポーネントの最上位ビットが設定されている場
合は 1 を返し、それ以外は 0 を返します。

vgentype bitselect (vgentype a, vgentype b, vgentype c)c の対応するビットが 0 である場合、結果の各ビットは a の対応するビットです。それ以外は b の対応するビットです。

vgentype select (vgentype a, vgentype b, vigeninteger c)

ベクトルタイプのコンポーネントごとに result[i] = (MSB of c[i]vgentype select (vgentype a, vgentype b, vugeninteger c)

is set) ? b[i] : a[i] を実行します。
vigeninteger と vugeninteger の 要 素 数 と ビ ッ ト 数 は 、vgentype と同じでなければなりません。

marray タイプとスカラー・データ・タイプで利用可能な関数を表 182 に示します。
表 182. marray テンプレート・クラスとスカラー・データ・タイプのリレーショナル関数
リレーショナル関数

説明bool isequal (sgenfloat x, sgenfloat y)x == y のコンポーネントごとの比較結果を返します。

marray<bool,{N}> isequal (mgenfloat x, mgenfloat y)bool isnotequal (sgenfloat x, sgenfloat y)x != y のコンポーネントごとの比較結果を返します。

marray<bool,{N}> isnotequal (mgenfloat x, mgenfloat y)bool isgreater (sgenfloat x, sgenfloat y)

x > y のコンポーネントごとの比較結果を返します。

marray<bool,{N}> isgreater (mgenfloat x, mgenfloat y)bool isgreaterequal (sgenfloat x, sgenfloat y)marray<bool,{N}> isgreaterequal (mgenfloat x, mgenfloaty)386 | 第 4 章 SYCL プログラミング・インターフェイス

x >= y のコンポーネントごとの比較結果を返します。

SYCL 2020 リビジョン 6 - 4.17 SYCL ホストとデバイス向けの SYCL ビルトイン関数

リレーショナル関数

説明bool isless (sgenfloat x, sgenfloat y)

x < y のコンポーネントごとの比較結果を返します。

marray<bool,{N}> isless (mgenfloat x, mgenfloat y)bool islessequal (sgenfloat x, sgenfloat y)x <= y のコンポーネントごとの比較結果を返します。

marray<bool,{N}> islessequal (mgenfloat x, mgenfloat y)bool islessgreater (sgenfloat x, sgenfloat y)(x < y) || (x > y) のコンポーネントごとの比較結果を返します。

marray<bool,{N}> islessgreater (mgenfloat x, mgenfloat y)bool isfinite (sgenfloat x)

有限値をテストします。

marray<bool,{N}> isfinite (mgenfloat x)
bool isinf (sgenfloat x)

無限大値 (正または負) をテストします。

marray<bool,{N}> isinf (mgenfloat x)
bool isnan (sgenfloat x)

NaN をテストします。

marray<bool,{N}> isnan (mgenfloat x)
bool isnormal (sgenfloat x)

正常値をテストします。

marray<bool,{N}> isnormal (mgenfloat x)
bool isordered (sgenfloat x, sgenfloat y)

引数が順序付けられているかテストします。isordered() は引数 xmarray<bool,{N}> isordered (mgenfloat x, mgenfloat y)と y を受け取り、結果 isequal(x, x) && isequal(y, y) を返します。

bool isunordered (sgenfloat x, sgenfloat y)

引数が順序付けられていないかテストします。isunordered() は、

marray<bool,{N}> isunordered (mgenfloat x, mgenfloat y)

引数 x と y を受け取り、x または y が NaN である場合は true を返し、それ以外は false を返します。

bool signbit (sgenfloat x)

符号ビットをテストし、x の符号ビットが設定されている場合はmarray<bool,{N}> signbit (mgenfloat x)

true を返し、それ以外は false を返します。

bool any (sigeninteger x)

x のいずれかのコンポーネントの最上位ビットが設定されている

bool any (migeninteger x)

場合は true を返し、それ以外は false を返します。

bool all (sigeninteger x)

x のすべてのコンポーネントの最上位ビットが設定されている場

bool all (migeninteger x)

合は true を返し、それ以外は false を返します。

sgentype bitselect (sgentype a, sgentype b, sgentype c)c の対応するビットが 0 である場合、結果の各ビットは a の対応

mgentype bitselect (mgentype a, mgentype b, mgentype

するビットです。それ以外は b の対応するビットです。

c)sgentype select (sgentype a, sgentype b, bool c)

コンポーネントごとの result = c ? b : a を返します。

mgentype select (mgentype a, mgentype b,marray<bool,{N}> c)

第 4 章 SYCL プログラミング・インターフェイス | 387

SYCL 2020 リビジョン 6 - 5.1 SYCL ソースファイルのオフラインコンパイル

第 5 章 SYCL デバイス・コンパイラー
このセクションでは、SYCL デバイス・コンパイラーの要件について説明します。このセクションで説明するほとんどの機能は、ターゲッ
トデバイスのベースとなる SYCL バックエンド機能と、移植性を維持するデバイスコードの要件の制限に関連します。

5.1. SYCL ソースファイルのオフラインコンパイル
SYCL デバイス・コンパイラーには、シングルソース・デバイス・コンパイラーと SMCP をサポートするデバイス・コンパイラーの 2 つがあります。
SYCL デバイス・コンパイラーは、C++ ソースファイルを読み込み、SYCL カーネルのみを抽出して、関連する SYCL ランタイムによってホストコードからエンキュー可能な形式のデバイスコードを出力します。SYCL ランタイムがカーネルを呼び出す方法は実装によって定義されますが、一般的には、デバイス・コンパイラーがコンパイルされたカーネルを含むヘッダーファイルを生成します。ホスト・コン
パイラーにコマンドライン・オプションを指定して、実装の SYCL ヘッダーファイルが生成されたヘッダーファイルを #include します。
SYCL 仕様は、SMCP を許容する実装アプローチを許可するように作成されています。ただし、SYCL コンパイラー、SYCL ランタイムおよびビルドシステムに必要なメカニズムは、プラットフォームとアプローチによって異なることがあるため、実装で定義されます。
SYCL シングルソース・デバイス・コンパイラーは、C++ ソースファイルを読み込んで、ホストコードとデバイスコードの両方を同時にコンパイルします。この仕様は、SYCL シングルソース・デバイス・コンパイラーがカーネルのデバイスコードを認識して出力する方法を定義しますが、ホストコンパイルについては触れていません。

5.2. カーネルの命名
SYCL カーネルは C++ ソースファイルから抽出され、実装定義の形式で保存されます。共有ソース・コンパイル・モデルでは、カーネル
はホスト・コンパイラーとデバイス・コンパイラーの両方で一意に識別される必要があります。これは、ホストのランタイムが、バックエ
ンド固有のホスト・ランタイム・インターフェイスを使用してカーネルをロードするために必要になります。
この要件から、カーネルの命名には次の規則が適用されます。

• カーネル名は C++ のタイプ名。
• カーネル名は名前空間スコープ (グローバル名前空間スコープを含む) で前方宣言可能である必要があり、名前空間スコープ以外で前方宣言することはできません。4.9.4.2 節で説明されるように、それが前方宣言されていなくても、カーネル呼び出しイン
ターフェイスでテンプレート引数として指定される場合、含まれる名前空間スコープ名と競合しない場合があります。
カーネル名が前方宣言可能であるという要件から、std 名前空間で宣言されたものなど、カーネル名の一部のタイ
プが無効化されます (宣言を std 名前空間に追加すると、未定義の動作となります)。

• カーネルが名前付き関数オブジェクト・タイプとして定義される場合、名前空間スコープで宣言されているか、それを含む名前空間スコープ内の名前と競合しない限り、名前は関数オブジェクトのタイプ名にできます。

• カーネルがラムダ関数として定義されている場合、4.9.4.2 節で説明されるように、カーネル呼び出しインターフェイスのオプションでタイプ名を指定できるため、開発者はデバッグやビルドオプション適用時のカーネル参照などでカーネル名を制御できます。

• カーネル関数がテンプレート・パラメーターに依存する場合、それらのテンプレート・パラメーターはカーネル名に含まれなければなりません。このようなカーネル名がカーネル呼び出しインターフェイスのテンプレート引数として指定される場合、カーネルが依存するテンプレート・パラメーターは名前空間スコープで前方宣言可能でなければなりません。
単一ソースと共有ソースの両方の実装で、デバイス・コンパイラーはソースコード内のカーネル呼び出し (parallel_for<kernelname>など) を検出して含まれるカーネルをコンパイルし、関連付けられたタイプ名とともに格納します。

388 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.3 関数のコンパイル
カーネルの形式とコンパイル方法の詳細は実装に任されます。デバイスで SYCL カーネルを抽出して実行するためのコンパイルとラン
タイムとのインターフェイスの詳細も実装依存であり、仕様では指定されません。

5.3. 関数のコンパイル
SYCL デバイス・コンパイラーは、#include ディレクティブで参照されるヘッダーファイルを含む、ユーザーが提供する C++ ソースファ
イル全体を解釈します。このソースファイルから、SYCL デバイス・コンパイラーはデバイスカーネルと、カーネルが呼び出す関数をコンパイルする必要があります。
デバイス・コンパイラーは、parallel_for などのカーネル起動コマンドへの呼び出しを検索することでカーネルを識別します。パラメー
ターの 1 つには、SYCL カーネル関数と呼ばれる関数オブジェクトがあり、この関数は常に void を返します。SYCL カーネル関数によって呼び出される関数もデバイス向けにコンパイルされ、それらの関数は SYCL カーネル関数とともにデバイス関数と呼ばれます。デバ
イス・コンパイラーは、デバイス関数から呼び出される関数を再帰的に検索します。これらの関数もデバイス向けにコンパイルされ、デバイス関数と呼ばれます。
以下のソースコードは 3 つの関数と、デバイス向けにコンパイルする必要がある関数を示すコメント付きのカーネル呼び出しを示しています。
1.

void f(handler& cgh) {2.

// 関数 "f" はデバイス向けにコンパイルされません

3.
4.

cgh.single_task([=] {5.

// このコードはデバイス向けにコンパイルされます

6.

g(); // この行は "g" のデバイス向けコンパイルを強制します

7.
8.

});
}

9.
10.

void g() {

11.
12.

// カーネルから呼び出されます。そのため "g" はデバイス向けにコンパイルされます
}

13.
14.

void h() {

15.
16.

// デバイス関数からは呼び出されないため、デバイス向けにコンパイルされません}

SYCL デバイス・コンパイラーがデバイス関数を正しくコンパイルするには、ソースファイル内のすべての関数が、デバイス関数であるかどうかにかかわらず、この仕様に従って構文的に正しい関数でなければなりません。構文的に正しい関数は、3.9.1 節で定義する最小要件である C++ のバージョンに準拠します。

5.4. デバイス関数の言語制限
デバイス関数は特定の制限に従う必要があります。これらの関数では、C++ の完全な機能セットを利用できません。次に制限事項のリストを示します。

• ポインターとポインターを含むオブジェクトは共有できます。ただし、ポインターが SYCL デバイス間またはホストと SYCL デバイ
ス間で渡される場合、デバイスが USM をサポートし、ポインターが USM メモリー領域のアドレスでない限り、デバイス上のポイ
ンターを逆参照すると動作は未定義となります (4.8 節を参照)。

• カーネルでのメモリーストレージ割り当ては許可されていません。デバイスのすべてのメモリー割り当ては、4.8 節で説明されるよ
うに、アクセサークラスや USM によりホスト上で行われます。そのため、ストレージを割り当てるデフォルトの割り当てオペレー

第 5 章 SYCL デバイス・コンパイラー | 389

SYCL 2020 リビジョン 6 - 5.5 ビルトインのスカラー・データ・タイプ
ター new のオーバーロードは、SYCL カーネルでは許可されません。プレースメント new オペレーターとストレージを割り当てないユーザー定義のオーバーロードが許可されます。

• カーネル関数は常に戻りタイプ void でなければなりません。従って、void に変換されない式を含む return 文 (カーネル関数から
return する) と、void ではないカーネルのラムダ・トレーリング・リターン・タイプは不正となります。

• ポリモーフィック・クラスの仮想継承を持つクラスの ODR は許可されます。ただし、デバイス関数で仮想メンバー関数を呼び出す
ことはできません。

• また、デバイス関数では、関数ポインターまたは参照を呼び出すこともできません。
• RTTI はデバイス関数では無効になっています。
• デバイス関数では、可変引数を持つ関数を呼び出すことはできません。
• デバイス関数内では例外処理を行うことはできません。noexcept は許可されます。
• デバイス関数の再帰呼び出しは許可されません。
• スレッドストレージの存続期間 (thread_local ストレージクラス指定子) を持つ変数は、デバイス関数で ODR 使用ができません。
• デバイス関数内で ODR 使用される静的ストレージの存続期間を持つ変数は、const または constexpr でありゼロまたは定数で初期化されている必要があります。
この制限により、デバイス関数が const または constexpr 以外のグルーバル変数にアクセスすることはできません。

• カーネルの規則は、カーネル関数オブジェクトとカーネルから呼び出されるすべての関数、オペレーター、メンバー関数、コンスト
ラクター、およびデストラクターに適用されます。これは、カーネルが SYCL で動作するように適合したライブラリー関数のみを利用できることを意味します。実行は、この仕様でカーネルが利用できることが明示されているカーネル内のライブラリー・ルーチ
ン以外をサポートする必要はありません。開発者は、4.17 節の SYCL ビルトイン関数を参照して、カーネルで使用できる関数を見つける必要があります。

• C++ の共用体に格納される特殊な SYCL ランタイムクラス (SYCL accessor や stream など) との対話は未定義の動作となります。

• デバイス関数から ODR で使用される変数や関数は、使用しているのと同じ変換単位で定義する必要があります。ただし、5.10.1 節で説明されるように、実装で SYCL_EXTERNAL マクロが定義されている場合、関数は異なる変換単位で定義されることがあります。

5.5. ビルトインのスカラー・データ・タイプ
SYCL デバイス・コンパイラーでは、表 183 に示すすべての標準 C++ 基本タイプのデバイス定義は、サイズとアライメントの両方がそのタイプのホスト定義と一致する必要があります。デバイス・コンパイラーは、プラットフォームのそれらのタイプ定義に基づいて、それらが一致するように事前構成することがあります。また、タイプが同じであることを確認するため、デバイス・コンパイラーのオプションが必要になる場合があります。
標準 C++ 標準の固定幅タイプ int8_t、int16_t、int32_t、int64_t は、ホストとデバイスの C++ 標準で定義されるサイズと同一でなけ
ればなりません。
表 183. SYCL でサポートされた基本データタイプ
基本データタイプ

説明

bool

true または false のいずれかである条件付きデータタイプ。
値 true は整数定数 1 に展開され、値 false は整数定数 0 に展開されます。

390 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.6 プリプロセッサー・ディレクティブとマクロ

基本データタイプ

説明char

C++ コア言語で定義される符号付き、または符号なしの 8 ビット整数。

signed charC++ コア言語で定義される符号付き 8 ビット整数。

unsigned charC++ コア言語で定義される符号なし 8 ビット整数。

short int

C++ コア言語で定義される (少なくとも) 符号付き 16 ビット整数。

unsigned short int

C++ コア言語で定義される (少なくとも) 符号なし 16 ビット整数。

int

C++ コア言語で定義される (少なくとも) 符号付き 16 ビット整数。

unsigned int

C++ コア言語で定義される (少なくとも) 符号なし 16 ビット整数。

long int

C++ コア言語で定義される (少なくとも) 符号付き 32 ビット整数。

unsigned long int

C++ コア言語で定義される (少なくとも) 符号なし 32 ビット整数。

long long int

C++ コア言語で定義される (少なくとも) 64 ビット整数。

unsigned long long int

C++ コア言語で定義される (少なくとも) 符号なし 64 ビット整数。

float

32 ビット浮動小数点。float データタイプは、IEEE 754 単精度ストレージ形式に準拠する必要があります。

double64 ビット浮動小数点。double データタイプは、IEEE 754 倍精度ストレージ形式に準拠する必要があります。このタイプは aspect::fp64 を持つデバイスでのみサポートされます。

5.6. プリプロセッサー・ディレクティブとマクロ
標準 C++ の前処理ディレクティブとマクロがサポートされます。次のプリプロセッサー・マクロは、すべての準拠する実装で定義する必要があります。

• SYCL_LANGUAGE_VERSION には、実装でサポートする SYCL 言語のバージョンとリビジョン番号を表す整数を設定します。このドキュメントに対応する定義の SYCL バージョンでは、SYCL_LANGUAGE_VERSION に整数 2020 を設定し、バージョンの後にリビジョンを表す 2 桁の整数が続きます。

• 実 装 が 3.13.1 節 で 説 明 さ れ る よ う に 、 明 示 的 に 指 定 さ れ る デ バ イ ス コ ピ ー 可 能 な タ イ プ を サ ポ ー ト す る 場 合 、
SYCL_DEVICE_COPYABLE は 1 に設定されます。それ以外は、デバイスコピー可能な実装の定義は C++ のコピーにフォールバック可能であり、sycl::is_device_copyable は無視されます。

• ソースファイルがホストバイナリーを生成しない SYCL デバイス・コンパイラーでコンパイルされると、__SYCL_DEVICE_ONLY__
は 1 に定義されます。

• ソースファイルが、ホストおよびデバイスバイナリーを生成する SYCL シングルソース・コンパイラーでコンパイルされると、__SYCL_SINGLE_SOURCE__ は 1 に定義されます。

• SYCL_FEATURE_SET_FULL は、SYCL 実装が完全な機能セットをサポートする場合は 1 に定義され、それ以外は未定義です。
詳細については付録 B を参照してください。

• SYCL_FEATURE_SET_REDUCED は、SYCL 実装が完全な機能セットではなく、縮小機能セットをサポートする場合は 1 に定義され、それ以外は未定義となります。詳細については付録 B を参照してください。

第 5 章 SYCL デバイス・コンパイラー | 391

SYCL 2020 リビジョン 6 - 5.7 オプションのカーネル機能• SYCL_EXTERNAL は、SYCL 関数とメンバー関数の外部リンクを SYCL カーネルにインクルードすることを可能にするオプショ
ンのマクロです。このマクロは実装が外部リンクをサポートする場合にのみ定義されます。詳細については 5.10.1 節を参照してください。
さらに、サポートされるそれぞれの SYCL バックエンドでは、4.1 節で説明されるプリプロセッサー・マクロは、準拠するすべての実装で定義されている必要があります。

5.7. オプションのカーネル機能
この SYCL 仕様で定義される多くのカーネル機能はオプションであるため、一部のデバイスではサポートされていても、ほかのデバイ
スではサポートされない可能性があります。4.6.4.3 節で説明するように、アプリケーションは、デバイスに関連するアスペクトが存在するかどうかをテストすることで、デバイスがこれらの機能をサポートするか確認できます。次のアスペクトは、オプションのカーネル機能に相当します。

• fp16• fp64• atomic64
さらに、5.8.1 節に示す次の C++ 属性は、すべてのデバイスで実行できるとは限らない方法でカーネルを強制的にコンパイルするため、オプションのカーネル機能に対応しています。

• reqd_work_group_size()• reqd_sub_group_size()
オプションのカーネル機能を使用する SYCL アプリケーションのソースコードの移植性を保証するには、SYCL 実装が特定の機能をサポートするかどうかにかかわりなく、すべての SYCL 実装はそれらのオプションを使用するデバイスコードをコンパイルできる必要があります。
オプションのカーネル機能を使用するアプリケーションは、その機能を使用するカーネルが、機能をサポートするデバイスにのみ送信
されることを確実にする必要があります。アプリケーションがセカンダリー・キューを使用してコマンドグループを送信する場合、コマ
ンドグループから送信されるカーネルは、プライマリー・キューとセカンダリー・キューの両方のデバイスでサポートされる機能のみを使用する必要があります。アプリケーションがカーネルの送信に失敗すると、実装はカーネル起動コマンド (parallel_for() など) からの
errc::kernel_not_supported エラーコードで同期例外をスローする必要があります。
次の例のように、SYCL アプリケーションが異なるオプション機能を使用する場合、同じ翻訳単位で複数のカーネルを定義することは許可されます。
1.

queue q1(dev1);2.

if (dev1.has(aspect::fp16)) {3.

q1.submit([&](handler& cgh) {4.

cgh.parallel_for<KernelA>(range{N}, [=](id i) {5.

half fpShort = 1.0;

6.

/* ...*/

7.

});

8.
9.

});
}

10.
11.

queue q2(dev2);12.

if (dev2.has(aspect::atomic64)) {13.

q2.submit([&](handler& cgh) {14.

cgh.parallel_for<KernelB>(range{N}, [=](id i) {392 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.8 デバイスコードの属性
15.

/* ...*/

16.

sycl::atomic_ref longAtomic(longValue);

17.

longAtomic.fetch_add(1);

18.

});

19.
20.

});
}

アプリケーションが実際にはデバイスにカーネルを送信しない場合、実装は投機的なデバイスカーネルのコンパイルが原因で、コンパ
イ ル 時 の 診 断 や 実 行 時 の 例 外 発 生 を 行 わ な い 場 合 が あ り ま す 。 上 記 の 例 を ベ ー ス に 説 明 す る た め 、 デ バ イ ス dev1 に はaspect::atomic64 がなく、デバイス dev2 には aspect::fp16 がないと想定します。デバイス dev2 の KernelA のコンパイル、またはデバイス dev1 の KernelB のコンパイルが原因で、アプリケーションがカーネルをデバイスに送信しないため、実装は診断を行うことができません。
この要件は、実装がカーネルをデバイスイメージにバンドルする方法に影響すると思われます。例えば、KernelA とKernelB を同一のデバイスイメージに単純にバンドルすると、KernelA が dev1 に送信されたときに実装がデバイ
スイメージ全体をコンパイルする際に、この要件に違反する可能性があります。

5.8. デバイスコードの属性
C++ 属性は、デバイス・コンパイラーが生成するコードに影響するため、カーネルとデバイス関数を修飾することができます。これらの属性はすべて [[sycl::]] 名前空間で定義されます。
このセクションで定義される属性トークンを特定のカーネルまたはデバイス関数に適用する場合、そのカーネルまたはデバイス関数の翻訳ユニット内の最初の宣言で適用しなければなりません。これを行わないプログラムは不正な形式であり、コンパイラーは診断を行う必要があります。同じ翻訳ユニット内のカーネルやデバイス関数の再宣言は、オプションで同じ属性を適用できますが (両方の宣言で属性引数が同じである場合)、これは必須ではありません。属性は、再宣言に現れるかどうかにかかわらず有効です。
属性の説明で特に明記されない限り、すべてのインスタンスに同じ属性引数がない限り、カーネルやデバイス関数を同じ属性の複数のインスタンスで宣言することはできません。コンパイラーはこの要件違反の診断を行う必要があります。カーネルまたはデバイス関数の宣言に同じ属性のインスタンスが 2 つ以上ある場合、その効果は 1 つのインスタンスが指定されたかのようになります (すべてのイ
ンスタンスが同じ属性引数を持つと想定)。
カーネルやデバイス関数がこれらの属性で修飾される場合、その修飾は翻訳単位内のカーネルまたはデバイス関数の最初の宣言になければなりません。これに従わないプログラムの形式は不正であり、コンパイラーは診断を行う必要があります。特定の翻訳単位で属性を指定して関数を宣言し、別の翻訳単位で同じ属性を適用せずに同じ関数を宣言するプログラムの形式は不正ですが診断は不要です。
これらの属性が、ホストとデバイス向けにコンパイルされるデバイス関数に適用される場合、関数がホスト向けにコンパイルされる際は効果がありません。
これらの属性をこのセクションで示す以外の言語構造に適用すると、実装で定義された効果が得られます。

5.8.1. カーネル属性
表 184 の属性は、カーネルがラムダ関数として定義されるか、名前付き関数オブジェクトとして定義されるかにより、位置が異なります。カーネルが名前付き関数の場合は、属性は関数宣言の宣言子 ID に適用され、ラムダ関数の場合はラムダ宣言子に適用されます。

第 5 章 SYCL デバイス・コンパイラー | 393

SYCL 2020 リビジョン 6 - 5.8 デバイスコードの属性

指定位置が異なる理由は、C++ コア言語では現在ラムダに対応する関数宣言子や演算子テンプレートに関連する属性の位置が定義されておらず、対応するタイプの関数演算子または演算子テンプレートのみに定義されているためです。これは、将来の C++ コア言語仕様で修正される予定です。
次の例では、[[sycl::reqd_work_group_size(16)]] 属性を使用してこの使い方を示しています。C++ コア言語では、名前付き関数オブジェクトとして定義されるカーネルに対して 2 つの指定位置が許可されることに注意してください。
1.

// ラムダとしてカーネルを定義

2.

myQueue.submit([&](handler&h) {3.

h.parallel_for( range<1>(16),4.

[=] (item<1> it) [[sycl::reqd_work_group_size(16)]] {5.

// [カーネルコード]

6.
7.

});
});

8.
9.

// 名前付き関数オブジェクトとして定義されたカーネル

10.

class KernelFunctor1 {11.

public:12.

[[sycl::reqd_work_group_size(16)]]

13.

void operator()(item<1> it) const {14.

// [カーネルコード]

15.
16.

};
};

17.
18.

// 名前付き関数オブジェクトとして定義されたカーネル

19.

class KernelFunctor2 {20.

public:21.

void operator() [[sycl::reqd_work_group_size(16)]] (item<1> it) const {22.

// [カーネルコード]

23.
24.

};
};

394 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.8 デバイスコードの属性
表 184. カーネル関数の属性
SYCL 属性

説明

reqd_work_group_size(dim0)

指定された work-group サイズでカーネルを起動する必要があ

reqd_work_group_size(dim0, dim1)

ることを示します。引数の数はカーネル呼び出しに使用される

reqd_work_group_size(dim0, dim1, dim2)

work-group の次元と一致する必要があり、引数の順番は range
コンストラクターへの次元範囲の順番と一致する必要があります。各引数は、整数定数式でなければなりません。
この属性で修飾されたカーネルは、SYCL_EXTERNAL マクロを介して異なる翻訳単位で定義されている関数を呼び出すことはできません。
各デバイスは、サポートする work-group のサイズが制限されることがあります。カーネルがそれらの属性で修飾され送信されると、要求する work-group サイズがサポートされないデバイスに対し、実装は errc:: kernel_not_supported エラーコードで例外
をスローする必要があります。work-group サイズでサポートされていても、アプリケーションが属性サイズと一致しない nd_range
を使用する場合、実装は errc::nd_range エラーコードで 例外をスローする必要があります。

work_group_size_hint(dim0)

実行時に カー ネル を起動す る際に 使用され る可能 性が 高い

work_group_size_hint(dim0, dim1)

work-group サイズに関するヒントをコンパイラーに提供します。

work_group_size_hint(dim0, dim1, dim2)

引数の数はカーネルの呼び出しで使用される work-group の次元と一致する必要があり、引数の順番は range コンストラクターへの次元範囲の順番と一致する必要があります。各引数は、整数
定数式でなければなりません。この属性の影響があるかどうかは実装定義です。

vec_type_hint(<type>)

コンパイラーにカーネルのベクトル計算幅のヒントを提供します。引数は、4.14.2 節で定義されるいずれかのベクトルタイプである必要があります。
この属性の影響があるかどうかは実装定義です。
この属性は非推奨です (利用できますが、将来の仕様で削除される可能性があり、新しいコードでの使用は推奨されません)。

第 5 章 SYCL デバイス・コンパイラー | 395

SYCL 2020 リビジョン 6 - 5.8 デバイスコードの属性

SYCL 属性

説明

reqd_sub_group_size(dim)指定された sub-group サイズでカーネルをコンパイルおよび実行する必要があることを示します。属性への引数は整数定数式でなければなりません。
この属性で修飾されたカーネルは、SYCL_EXTERNAL マクロを介して異なる翻訳単位で定義されている関数を呼び出すことはできません。
各 デ バ イ ス は 、 info::device::sub_group_sizes で 定 義 さ れ る
work-group サイズのみをサポートします。また、一部のデバイス
機能は、特定の work-group サイズと互換性がないことがあります。カーネルがこの属性で修飾され送信された場合、またはカーネルがその sub-group サイズでデバイスがサポートしない機能を使用した場合、実装は errc::kernel_not_supported エラー
コードで例外をスローする必要があります。

device_has(aspect, ...)

この属性は、現在の翻訳単位で定義されるカーネル関数の宣言を修飾するか、カーネル以外のデバイス関数の宣言を修飾するために使用できます。以下は、属性がカーネル関数を修飾する際に適用されます。
sycl::device_has() 属性へのパラメーター・リストは、0 個以上の整数定数式で構成され、それぞれの整数は sycl::aspect 列挙値の1 つとして解釈されます。
カーネルでこの属性を指定すると 2 つの効果があります。
1つは、カーネルがリストされたアスペクトを持たないデバイスに 送 信 さ れ た 場 合 、 カ ー ネ ル 起 動 コ マ ン ド が
errc::kernel_not_supported エ ラ ー コ ー ド で 同 期 例 外 を ス
ローします (これには、カーネルがセカンダリー・キューを持つコ
マンドグループから送信された場合に、セカンダリー・キューに関連付けられたデバイスが含まれます)。2 つ目は、カーネル (またはカーネルが呼び出す関数) が属性にリストされていないア
スペクトに関連付けられたオプション機能を使用すると、コンパ
イラーは診断を行います。
この属性の各パラメーター値は、sycl::aspect 列挙タイプの値の1 つと等しくなければなりません (実行が提供する拡張値も含みます)。そうでなければ、プログラムの形式が正しくないためコン
パイラーは診断を行う必要があります。
この属性の例についてはリスト 3 をご覧ください。

リスト 3. sycl::requires() 属性の例
1.
2.

class KernelFunctor {public:3.

[[sycl::device_has ( aspect::fp16)]]

4.

void operator()(item<1> it) const {5.

foo();

6.

bar();

7.

};

396 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.8 デバイスコードの属性
8.
9.

private:10.

void foo() const {11.

half fp = 1.0; // ここではコンパイラーの診断はありません

12.

}

13.
14.

void bar() const {15.

sycl::atomic_ref longAtomic(longValue);

16.

longAtomic.fetchAdd(1); // エラー: "device_has()" に "aspect::atomic64" がないため、

17.

// コンパイラーは診断を発行

18.
19.

}
};

20.
21.

// "sycl:: device_has()" を使用しても、デバイスが必要な機能を

22.

// 実際にサポートするという保証はありません。従って、ホストコードはカーネルを送信する前に、

23.

// デバイスのアスペクトをチェックする必要があります。

24.

if (myQueue.get_device().has(aspect::fp16)) {25.

myQueue.submit([&](handler& h) {26.

h.parallel_for(range{16}, KernelFunctor{});

27.
28.

});
}

5.8.2. デバイス関数属性
表 185 の属性は、非カーネルデバイス関数の宣言に適用されます。属性の位置は、5.8.1 節で定義されるカーネル関数属性と同じです。

第 5 章 SYCL デバイス・コンパイラー | 397

SYCL 2020 リビジョン 6 - 5.9 アドレス空間の推定表 185. 非カーネルデバイス関数の属性
SYCL 属性

説明

sycl::device_has (aspect, ...)

この属性は、現在の翻訳単位で定義されるカーネル関数の宣言を修飾するか、カーネル以外のデバイス関数の宣言を修飾するために使用できます。以下は、属性が非カーネルデバイス関数を修飾する際に適用されます。
この属性のパラメーター・リストの構文は、カーネル関数で指定される sycl::device_has() 形式の構文と同一です (表 184 を参照)。
この属性は、オプションのデバイス機能を使用する非カーネルデバイス関数が同一の翻訳単位で呼び出され、SYCL_EXTERNAL
マクロにより別の翻訳単位が定義されている場合に有効です。
修飾されたデバイス関数を呼び出す翻訳単位でこの属性が現れると、これはデバイス関数が属性にリストされるアスペクトに対応するオプション機能を使用することを通知します。呼び出されたデバイス関数が属性で指定されるアスペクトのどれにも対応しないオプション機能を使用する場合、もしくは関数がオプション
機能を使用しているにもかかわらず属性が指定されていない場
合、そのプログラムは不正な形式です。これには診断は必要ありません。
その属性が修飾されるデバイス関数を定義する翻訳単位で出現
すると、デバイス関数 (または呼び出す関数) が属性リストで指定されていないアスペクトに関連付けられたオプション機能を使用する場合、コンパイラーは診断を行います。

5.9. アドレス空間の推定
C++ には、アドレス空間を表現するタイプレベルのサポートがありません。つまり、SYCL ジェネリック・プログラミング・モデルでは、注釈のないポインターと参照の C++ タイプは直接影響しません。
SYCL ジェネリック・プログラミング・モデルのアドレス空間に対するソースレベルの保証は、対応するアドレス空間に格納されているデータへのポインターを表す通常のクラスであるポインタークラス (multi_ptr のインスタンス) を使用してのみ達成できます。
SYCL では、ポインターと参照アドレス空間は以下から派生します:。

• 共有データへのアクセスを提供するアクセサー。コマンドグループのメモリー・オブジェクトにバインドしてカーネルに渡すことができます。アクセサーは、カーネルをスケジュールする順番を定義するために使用されます。バッファーへのアクセサーは、アドレ
スモードに基づいたコンパイル時のアドレス空間を持ちます。

• 明示的なポインタークラス (global_ptr など) は、access::address_space によって表現されるアドレス空間をアドレス指定する
ポインターを保持します。これにより、コンパイラーはポインターがグローバル、ローカル、定数、またはプライベート・メモリーのいずれを参照しているか判断し、対応したコードを生成します。

• 生の C++ ポインターや参照タイプ (int* など) は、SYCL カーネル内で使用できます。これらは、ローカル変数、明示的なポイン
タークラス、またはアクセサーのアドレスから構築できます。

398 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.9 アドレス空間の推定

5.9.1. アドレス空間の割り当て
データが存在する場所を確認するため、デバイス・コンパイラーは、コンテキストに基づいたベースとなるターゲットのタイプを降格させながらアドレス空間を割り当てることが期待されます。SYCL バックエンドとモードに応じて、アドレス空間の推定規則は若干異なります。
SYCL バックエンドのターゲットがジェネリックなアドレス空間を表現できる場合、5.9.2 節の「共通アドレス空間の推定規則」と、5.9.3
節の「デフォルトアドレス空間としての汎用性」が適用されます。SYCL バックエンドのターゲットがジェネリックなアドレス空間を表現できない場合、5.9.2 節の「共通アドレス空間の推定規則」と、5.9.4 節の「推定アドレス空間」が適用されます。
SYCL アドレス空間はタイプに影響しません。アドレス空間は、データが割り当てられるメモリーセグメントとして理解されます。例えば、int i; がグローバルアドレス空間に割り当てられると、decltype(&i) は int* を評価する必要があります。

5.9.2. 共通アドレス空間の推定規則宣言された変数は、スコープとストレージクラスに応じてアドレス空間に割り当てられます。

• 名前空間スコープ◦ タイプが const である場合、宣言された変数が割り当てられるアドレス空間は実装定義です。SYCL バックエンドのターゲットがジェネリック・アドレス空間を表現できる場合、割り当てられたアドレス空間は汎用アドレス空間と互換性を持つ必要があります。
5.4 節で説明されるように、名前空間スコープの非 const 宣言は、カーネル内では使用できません。これは、デバイ
スカーネルまたはカーネルから呼び出されるコードから、const 以外のグローバル変数にアクセスできないことを意味します。

• ブロックスコープと関数パラメーター・スコープ◦ 静的ストレージの存続期間の宣言は、名前空間スコープの変数と同様に扱われます。
◦ それ以外は、階層コンテキストで宣言されていればローカルアドレス空間に割り当てられます。
◦ それ以外は、宣言はプライベート・アドレス空間に割り当てられます。
• クラススコープ◦ 静的データメンバーは名前空間スコープの変数と同様に扱われます。
prvalue から xvalue への変換が階層的なコンテキストで生じる場合、結果はローカルアドレス空間に、それ以外はプライベート・アド
レス空間に割り当てられます。

5.9.3. デフォルトアドレス空間としての汎用性
汎用アドレス空間を表現できる SYCL バックエンド (5.9.1 節を参照) では、注釈のないポインターと参照は汎用アドレス空間を指していると見なされます。

第 5 章 SYCL デバイス・コンパイラー | 399

SYCL 2020 リビジョン 6 - 5.10 SYCL オフラインリンク

5.9.4. 推定アドレス空間
このバージョンでの注意
次に示すアドレス空間の推定機能は、SYCL 1.2.1 仕様から継承されています。このアクションは、将来のバージョンで変更され、汎用アドレス空間の追加と、デフォルトのアドレス空間としてジェネリックが調整される予定です。
汎用アドレス空間を表現できない SYCL バックエンド (5.9.1 節を参照) では、SYCL デバイス・コンパイラーは C++ から基本表現へのタイプに降格する際に、注釈のないポインターや参照タイプのメモリー領域を自動的に推定する必要があります。
カーネル関数やデバイス関数にポインターまたは参照タイプが含まれる場合、次の規則を適用してアドレス空間を推定する必要があります。

• 明示的なポインタークラスが C++ ポインター値に変換される場合、C++ ポインター値は明示的なポインタークラスと同じアドレ
ス空間を指します。

• 変数がポインタータイプとして宣言され、その宣言ですでに推定されたアドレス空間を持つポインター値に初期化されている場
合、その変数は初期化子と同じアドレス空間を持ちます。

• 関数パラメーターがポインタータイプとして宣言され、引数が推定アドレス空間を持つポインター値である場合、関数はパラメー
ターが引数と同じアドレス空間を持つようにコンパイルされます。引数に異なるアドレス空間を指定して、関数を異なる場所で呼び出すことは許可されますが、その場合、関数は「複製」され、複数回コンパイルされたと見なされます。複製された関数の各イン
スタンスは、動作を定義するため規則に則ってコンパイルする必要があります。

• 関数の戻りタイプがポインターとして宣言され return 文がアドレス空間推定式を使用する場合、関数は戻りタイプが同じアドレ
ス空間を持つかのようにコンパイルされます。規則に則ってコンパイルするには、すべての戻り式が同じアドレス空間に推定される必要があります。

• ポインタータイプの規則は、参照タイプにも適用されます。つまり、参照変数はその初期化子からアドレス空間を取得します。参照
パラメーターを持つ変数は、引数からアドレス空間を取得します。

• 上記のほかの規則を適用できないポインター宣言は、プライベート・アドレス空間にあると見なされます。
特定のアドレス空間を指すポインター値を、別のアドレス空間を指すポインター変数に割り当てることは不正です。

5.10. SYCL オフラインリンク
5.10.1. SYCL 関数とメンバー関数のリンク
デフォルトでは、デバイス関数から ODR で使用される関数は、同じ変換単位で定義する必要があります。ただし、次の両方の条件を満たす場合、この制限は緩和されます。

• 実装が SYCL_EXTERNAL マクロを定義します。
• 関数を呼び出す翻訳単位は、以下で説明するように、SYCL_EXTERNAL を使用して関数を宣言します。
関数が SYCL_EXTERNAL で宣言されている場合、このマクロは翻訳単位のその関数の最初の宣言で使用される必要があります。同じ
翻訳単位の関数の再宣言では、オプションで SYCL_EXTERNAL を使用できますが、これは必須ではありません。
関数が SYCL_EXTERNAL で宣言されている場合、その関数は関数が SYCL_EXTERNAL で宣言されている翻訳単位でも定義される
必要があります。
関数は、通常の C++ の規則で外部リンクがある場合にのみ、SYCL_EXTERNALで宣言することができます。

400 | 第 5 章 SYCL デバイス・コンパイラー

SYCL 2020 リビジョン 6 - 5.10 SYCL オフラインリンク
SYCL_EXTERNAL で宣言された関数は、ホストコードとデバイスコードの両方から呼び出すことができます。関数がホストコードから呼び出されると、マクロの効果はありません。
SYCL_EXTERNAL を使用して関数を宣言するには、関数宣言の前にマクロ名 SYCL_EXTERNAL を記述する必要があります。関数が宣言の前に C++ 属性で修飾されている場合、SYCL_EXTERNAL はそれらの属性の前後、または中間に現れることがあります。次の例
は、SYCL_EXTERNAL の使い方を示しています。
1.

#include <sycl/sycl.hpp>

2.
3.

SYCL_EXTERNAL void Foo();

4.
5.

SYCL_EXTERNAL void Bar() ｛ /* ... */ ｝

6.
7.

SYCL_EXTERNAL extern void Baz();8.
9.

[[nodiscard]] SYCL_EXTERNAL void Important();

10.
11.

SYCL_EXTERNAL [[nodiscard]] void AlsoImportant();

SYCL_EXTERNAL を使用して宣言された関数は、デバイス関数に影響する制限以外にも、次の制限があります。

• SYCL バックエンドが汎用アドレス空間をサポートしていない場合、関数は生のポインターをパラメーターや戻り値のタイプとして使用することはできません。代わりに明示的なポインタークラスを使用します。

• 関数は group::parallel_for_work_item を呼び出すことはできません。
• 関数は parallel_for_work_group スコープから呼び出すことはできません。

第 5 章 SYCL デバイス・コンパイラー | 401

SYCL 2020 リビジョン 6 - 6.1 拡張機能の定義

第 6 章 SYCL 拡張
この章では、コア SYCL 仕様を拡張するメカニズムについて説明します。この章には、コア SYCL 仕様を拡張する際に従わなければな
らない要件が含まれますが、それ以外は単なるガイドラインです。要件が規範的であると明記されていない限り、この章のすべての内容
は非規範的ガイドラインです。
拡張機能には、Khronos SYCL グループによって承認された拡張とベンダー提供の拡張の 2 つがあります。どちらもオプションの機能セットであり、コア SYCL 仕様に準拠するためには実装は必須ではありません。
ベンダーは、カスタム機能を実装したり、コア SYCL 仕様を完全にサポートできない API に関するフィードバックを収集するため、拡張機能を定義することを選択できます。ベンダーの拡張機能が安定したら、それをコア SYCL 仕様の将来のバージョンで承認されるよう
Khronos 拡張に昇格することが推奨されます。つまり、ベンダー拡張は将来の SYCL バージョンで考慮すべき機能の候補であると見なすことができます。
Khronos SYCL グループは、コア SYCL 仕様では未対応であっても、複数ベンダーによって実装されている機能拡張を定義する場合があります。これらの拡張機能は、コア SYCL 仕様の将来のバージョンに含めることが検討される可能性もあります。
この章では SYCL の特定の拡張についてではなく、拡張機能を定義するメカニズムについて説明します。それぞれの拡張機能は、個別のドキュメントによって定義され、Khronos SYCL グループが拡張機能を承認すると、対応するドキュメントがリリースされます。ベン
ダー定義の拡張機能の場合、ベンダーがドキュメントをリリースする責任を負います。

6.1. 拡張機能の定義
拡張機能はさまざまな形式をとることができます。次に例を示します。

• 新しいタイプまたはフリー関数を SYCL ランタイムに追加する。
• 新しいメンバー、メンバー関数、または列挙値を追加して、既存の SYCL クラス、構造体、または列挙タイプを変更する。
• 既存のフリー関数またはメンバー関数に新しいオーバーロードを追加する。
• 既存の SYCL テンプレートの新しい特殊化を定義する。
• 新しい C++ 属性を追加する。
• 新しい事前定義済みマクロを追加する。
• 言語に新しいキーワードを追加する。
• 新しいバックエンドを追加する。
拡張機能は、コア SYCL 仕様で指定されないセマンティクスを定義することで、コア SYCL 仕様で定義される既存の関数を拡張することができます。

6.2. 拡張機能の要件
このセクションは規範的です。拡張機能を提供するすべてのベンダーは、ここに示す要件に従う必要があります。
拡張機能は、コア SYCL 仕様で定義される既存の関数の動作を変更することはできません。また、コア SYCL 仕様で定義される機能を削除することもできません。
ベンダーは、ベンダーの SYCL 実装を一意に識別するため、少なくとも 1 つの <vendorstring> を選択する必要があります。

402 | 第 6 章 SYCL 拡張

SYCL 2020 リビジョン 6 - 6.3 ポータブルな拡張のガイドライン
Khronos SYCL グループは、文字列レジストリーを提供しないため、ベンダーは独自の文字列を選択しなければなりません。一意の文字列を選択するには、ベンダーの社名またはベンダーの実装に関連するマーケティング名を使用します。最終的に、一意の文字列を決定するのはベンダーの責任です。文字列 "khr" と "KHR" は、Khronos SYCL グループの独自拡張向けに予約されているため、ベンダー
はこれを <vendorstring> として利用できません。
実装では、SYCL_IMPLEMENTATION_<vendorstring> 形式のマクロを少なくとも 1 つ、事前定義する必要があります。これにより、
ア プ リ ケ ー シ ョ ン が ベ ン ダ ー の 実 装 で コ ン パ イ ル さ れ て い る か テ ス ト す る こ と が で き ま す 。 例 え ば 、 ベ ン ダ ー Acme は 、
SYCL_IMPLEMENTATION_ACME というマクロ名を事前定義できます。

6.3. ポータブルな拡張のガイドライン
それぞれのベンダーの拡張機能が他社の拡張機能やコア SYCL 仕様の将来のバージョンと競合しないようにするには、このセクションで示す追加規則に従う必要があります。ただし、これは適合のための条件ではありません。

6.3.1. 拡張名前空間
拡張機能が新しいタイプやフリー関数を追加する場合、コア SYCL 仕様の将来のバージョンでもその名前空間に新しい識別子が追加される可能性があるため、それらを sycl:: 名前空間に直接追加するのは避けてください。名前空間 sycl::ext::<vendorstring> は、拡張機能向けに予約されています。例えば、Acme ベンダーは名前空間 sycl::ext::acme に拡張タイプとフリー関数を定義できます。これにより、ほかのベンダーの拡張機能やコア SYCL 仕様の将来のバージョンの定義と競合しないことが保証されます。

6.3.2. 既存のクラスまたは列挙の拡張名
拡張機能は、既存の SYCL クラスに新しいメンバーやメンバー関数を追加したり、既存の SYCL 列挙タイプに新しい値を追加することができます。これらの拡張機能が競合しないように、ベンダーはプリフィクス ext_<vendorstring>_ を付けて命名することを推奨します。例えば、Acme ベンダーは device::ext_acme_fancy() という名前の sycl::device クラスに新しいメンバー関数を追加するか、
aspect::ext_acme_fancier という名前の sycl::aspect 列挙に新しい値を追加できます。
状況によっては、拡張機能は特定の関数名を選択できないことがあります。例えば、拡張機能が既存の SYCL クラスに新しいコンスト
ラクター・オーバーロードを追加する場合などがあります。このような場合、拡張機能は関数パラメーターに拡張機能の名前空間で定義されているタイプがあることを確認する必要があります。例えば、Acme ベンダーは、署名 context(ext::acme::frobber&) を使用して、sycl::context の新しいコンテキストを追加できます。
既存の SYCL テンプレートが拡張された列挙値で特殊化されている場合、同様の状況になることがあります。この状況では明らかに、
拡張機能はテンプレート名を変更できません。代わりに、テンプレートが拡張された列挙値で特殊化されていれば十分であり、これにより拡張された特殊化が競合しないことが保証されます。
ベンダーが既存の SYCL クラスに追加を行うには、可能であれば ext_<vendorstring>_ プリフィクス形式を使用することを推奨します。このプリフィクスにより拡張機能のベンダー名が明確になります。アプリケーション・コードを読む際に、メンバー関数が拡張機能であることがすぐに分かり、参照すべきベンダーのドキュメントが明確になします。

6.3.3. 機能を評価するマクロベンダーは、関連する拡張セットを「機能」としてグループ化し、実装がその機能の拡張をサポートする場合に機能テストマクロを事前定義することを推奨します。機能テストマクロは、一意であることを確実にするため次の形式でなければなりません。
SYCL_EXT_<vendorstring>_<featurename>。

第 6 章 SYCL 拡張 | 403

SYCL 2020 リビジョン 6 - 6.3 ポータブルな拡張のガイドライン
例えば、Acme ベンダーは、SYCL_EXT_ACME_FANCYFEATURE という名前の機能テストマクロを定義します。これにより、アプリ
ケーションは #ifdef 文によって拡張機能を使用してコードを保護できるため、この機能をサポートしない実装でコンパイルするとコードはスキップされます。
拡張機能へのインターフェイスはリリースごとに変更される可能性があるため、ベンダーはマクロ値を拡張機能のバージョンごとに事前定義することも推奨されます。ベンダーは、拡張 API のリビジョンごとに一定間隔で増加する数値を使用する必要があります。
もちろん、拡張機能はほかのマクロを事前定義することもできます。これらのマクロ名がほかの拡張機能やコア SYCL 仕様の将来のバージョンと競合しないよう、名前はプリフィクス SYCL_EXT_<vendorstring> または SYCL_IMPLEMENTATION_<vendorstring>
で始める必要があります。

6.3.4. 属性名前空間
拡張機能は新しい C++ 属性を定義する場合があります。属性の名前空間 sycl:: はコア SYCL 仕様で予約されているため、ベンダーは追加する属性に対し別の名前空間を選択する必要があります。

6.3.5. インクルード・ファイル・パス
拡張機能は、"sycl" パスの下に新しい #include ファイルを定義します。パスのプリフィクス "sycl/ext/<vendorstring>" は、この用途に予約されています。例えば、Acme ベンダーはヘッダーファイル "sycl/ext/acme/fancy.h" を追加して、ほかの拡張機能やコア SYCL
仕様の将来のバージョンと競合しないことを保証できます。

6.3.6. オプションのカーネル機能
拡張機能は、新しいオプションのカーネル機能 (一部のデバイスではサポートされますが、ほかのデバイスではサポートされない機能)を追加することもあります。ベンダーは、5.7 節で示すメカニズムに従うことが推奨されます。従って、拡張オプションのカーネル機能には、sycl::aspect 列挙タイプに一致する拡張が必要です。

6.3.7. バックエンドの追加
拡張機能は新しいバックエンドを追加することもできます。その場合、バックエンド API の命令は拡張機能のガイドラインに従い、さらにコア SYCL 仕様で定義されるバックエンドの命令パターンにも従う必要があります。以下に例を示します。

• 拡張機能は、ext_<vendorstring>_<backendname> などの命名スキームを使用して、sycl::backend 列挙タイプに新しい値を追加します。例えば、Acme ベンダーが「foo」という名前のバックエンドを追加する場合、sycl::backend::ext_acme_foo という名前の列挙値を追加します。

• 拡張機能は、sycl::ext::<vendorstring>::<backendname> 形式の名前空間でバックエンドの相互運用 API を定義しなければなりません。Acme の例では、これは sycl::ext::acme::foo という名前空間になります。

• バックエンドの相互運用 API が別のヘッダーファイルで使用できる場合、そのヘッダーは次のように命名する必要があります。
"sycl/ext/<vendorstring>/backend/<backendname>.hpp"
Acme の例では、これは "sycl/ext/acme/backend/foo.hpp" になります。

• 拡張機能は、バックエンドが「アクティブ」なときのマクロを事前定義します。このマクロ名は次のようにする必要があります。
SYCL_EXT_<vendorstring>_BACKEND_<backendname>Acme の例では、これは SYCL_EXT_ACME_BACKEND_FOO になります。

404 | 第 6 章 SYCL 拡張

SYCL 2020 リビジョン 6 - A.1 プラットフォーム情報記述子

付録 A 情報記述子
この章では、第 4 章で説明されているすべての SYCL 情報記述子の定義を示します。

A.1.

プラットフォーム情報記述子

次のインターフェイスには、表 18 で説明される platform クラスのすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace platform {4.
5.

struct profile;6.

struct version;

7.

struct name;8.

struct vendor;

9.

struct extensions; // 非推奨

10.
11.
12.
13.

A.2.

} // namespace platform} // namespace info
} // namespace sycl

コンテキスト情報記述子

次のインターフェイスには、表 21 で説明される context クラスのすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace context

{

4.
5.

struct platform;

6.

struct devices;7.

struct atomic_memory_order_capabilities;

8.

struct atomic_fence_order_capabilities;

9.

struct atomic_memory_scope_capabilities;

10.

struct atomic_fence_scope_capabilities;

11.
12.
13.
14.

A.3.

} // namespace context} // namespace info
} // namespace sycl

デバイス情報記述子

次のインターフェイスには、表 25 で説明される device クラスのすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace device {4.

付録 A 情報記述子 | 405

SYCL 2020 リビジョン 6 - A.3 デバイス情報記述子
5.

struct device_type;6.

struct vendor_id;

7.

struct max_compute_units;

8.

struct max_work_item_dimensions;9.

template<int Dimensions = 3> struct max_work_item_sizes;

10.

struct max_work_group_size;

11.

struct preferred_vector_width_char;

12.

struct preferred_vector_width_short;

13.

struct preferred_vector_width_int;

14.

struct preferred_vector_width_long;15.

struct preferred_vector_width_float;

16.

struct preferred_vector_width_double;

17.

struct preferred_vector_width_half;18.

struct native_vector_width_char;

19.

struct native_vector_width_short;

20.

struct native_vector_width_int;21.

struct native_vector_width_long;22.

struct native_vector_width_float;

23.

struct native_vector_width_double;

24.

struct native_vector_width_half;25.

struct max_clock_frequency;

26.

struct address_bits;

27.

struct max_mem_alloc_size;

28.

struct image_support; // 非推奨29.

struct max_read_image_args;

30.

struct max_write_image_args;

31.

struct image2d_max_height;

32.

struct image2d_max_width;33.

struct image3d_max_height;

34.

struct image3d_max_width;35.

struct image3d_max_depth;

36.

struct image_max_buffer_size;

37.

struct max_samplers;

38.

struct max_parameter_size;

39.

struct mem_base_addr_align;40.

struct half_fp_config;

41.

struct single_fp_config;

42.

struct double_fp_config;

43.

struct global_mem_cache_type;44.

struct global_mem_cache_line_size;

45.

struct global_mem_cache_size;

46.

struct global_mem_size;

47.

struct max_constant_buffer_size; // 非推奨

48.

struct max_constant_args; // 非推奨49.

struct local_mem_type;50.

struct local_mem_size;

51.

struct error_correction_support;

52.

struct host_unified_memory;53.

struct atomic_memory_order_capabilities;

54.

struct atomic_fence_order_capabilities;

55.

struct atomic_memory_scope_capabilities;

56.

struct atomic_fence_scope_capabilities;

406 | 付録 A 情報記述子SYCL 2020 リビジョン 6 - A.3 デバイス情報記述子
57.

struct profiling_timer_resolution;

58.

struct is_endian_little;

59.

struct is_available;

60.

struct is_compiler_available; // 非推奨61.

struct is_linker_available; // 非推奨

62.

struct execution_capabilities;

63.

struct queue_profiling; // 非推奨64.

struct built_in_kernels; // 非推奨65.

struct built_in_kernel_ids;

66.

struct platform;

67.

struct name;68.

struct vendor;

69.

struct driver_version;70.

struct profile;71.

struct version;72.

struct backend_version;73.

struct aspects;

74.

struct extensions; // 非推奨75.

struct printf_buffer_size;

76.

struct preferred_interop_user_sync;

77.

struct parent_device;78.

struct partition_max_sub_devices;79.

struct partition_properties;

80.

struct partition_affinity_domains;

81.

struct partition_type_property;

82.

struct partition_type_affinity_domain;

83.
84.

} // namespace device

85.
86.

enum class device_type : /* 未定義 */ {

87.

cpu,

// OpenCL CL_DEVICE_TYPE_CPU へマップ

88.

gpu,

// OpenCL CL_DEVICE_TYPE_GPU へマップ

89.

accelerator, // OpenCL CL_DEVICE_TYPE_ACCELERATOR へマップ

90.

custom, // OpenCL CL_DEVICE_TYPE_CUSTOM へマップ

91.

automatic,

92.

host,

93.

all

94.

// OpenCL CL_DEVICE_TYPE_DEFAULT へマップ// OpenCL CL_DEVICE_TYPE_ALL マップ

};

95.
96.

enum class partition_property : /* 未定義 */ {97.

no_partition,

98.

partition_equally,

99.

partition_by_counts,

100.

partition_by_affinity_domain

101.

};

102.
103.

enum class partition_affinity_domain : /* 未定義 */ {104.

not_applicable,

105.

numa,

106.

L4_cache,107.

L3_cache,108.

L2_cache,

付録 A 情報記述子 | 407

SYCL 2020 リビジョン 6 - A.4 キュー情報記述子109.

L1_cache,

110.
111.

next_partitionable
};

112.
113.

enum class local_mem_type : /* 未定義 */ {

114.

none,

115.

local,

116.

global

117.

};

118.
119.

enum class fp_config : /* 未定義 */ {120.

denorm,121.

inf_nan,122.

round_to_nearest,

123.

round_to_zero,124.

round_to_inf,

125.

fma,

126.

correctly_rounded_divide_sqrt,

127.
128.

soft_float
};

129.
130.

enum class global_mem_cache_type : /* 未定義 */ {

131.

none,

132.

read_only,133.

read_write

134.

};

135.
136.

enum class execution_capability : /* 未定義 */ {137.

exec_kernel,

138.

exec_native_kernel

139.

};

140.
141.
142.

A.4.

} // namespace info
} // namespace sycl

キュー情報記述子

次のインターフェイスには、表 30 で説明される queue クラスのすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace queue {4.
5.

struct context;

6.

struct device;

7.
8.
9.
10.

} // namespace queue} // namespace info
} // namespace sycl

408 | 付録 A 情報記述子SYCL 2020 リビジョン 6 - A.5 カーネル情報記述子

A.5.

カーネル情報記述子

次のインターフェイスには、表 136 で説明されるカーネルに適用されるすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace kernel {4.
5.

struct num_args;

6.

struct attributes;

7.
8.

} // namespace kernel

9.
10.

namespace kernel_device_specific {

11.
12.

struct global_work_size;

13.

struct work_group_size;

14.

struct compile_work_group_size;

15.

struct preferred_work_group_size_multiple;

16.

struct private_mem_size;

17.

struct max_num_sub_groups;

18.

struct compile_num_sub_groups;

19.

struct max_sub_group_size;

20.

struct compile_sub_group_size;

21.
22.

} // namespace kernel_device_specific

23.
24.
25.

A.6.

} // namespace info
} // namespace sycl

イベント情報記述子

次のインターフェイスには、表 35 および表 36 で説明される event クラスのすべての情報記述子が含まれます。
1.
2.
3.

namespace sycl {namespace info {namespace event {4.
5.

struct command_execution_status;

6.
7.

} // namespace event

8.
9.

enum class event_command_status : /* 未定義 */ {10.

submitted,

11.

running,

12.

complete

13.

};

14.
15.

namespace event_profiling {

16.
17.

struct command_submit;

付録 A 情報記述子 | 409

SYCL 2020 リビジョン 6 - A.6 イベント情報記述子
18.

struct command_start;

19.

struct command_end;

20.
21.
22.
23.

} // namespace event_profiling} // namespace info
} // namespace sycl

410 | 付録 A 情報記述子SYCL 2020 リビジョン 6 - B.1 完全な機能セット

付録 B 機能セット
SYCL 2020 には、組込み、モバイル、セーフティー・クリティカルなどさまざまなドメインの要件により良く適合するため、SYCL 実装が準拠できる 2 つの異なる機能セットがあります。
SYCL の実装は、完全な機能セットまたは縮小された機能セットのどちらに準拠するかを選択できます。

B.1.

完全な機能セット

完全な機能セットには、コア SYCL 仕様で定義されているすべての機能が含まれます。例外はありません。

B.2.

縮小された機能セット縮小された機能セットでは、特定の機能がオプションになったり、特定の形式に制限されたりします。次のリストは、縮小された機能セットと完全な機能セットの違いを示します。
1.

名前を持たない SYCL カーネル関数: ラムダ関数によって定義されるSYCL カーネル関数は、標準名を持たないため
parallel_for などのカーネル呼び出し関数のカーネル名テンプレート・パラメーターによって名前を指定する必要があります。これは、4.9.4.2 節に示される SYCL カーネル関数の命名に関するコア SYCL 仕様規則を変更します。

2.

アドレス空間モード: 縮小された機能セットで使用されるアドレス空間の割り当てモードは、使用する SYCL バックエンドにかかわりなく、汎用アドレス空間である必要はありません。代わりに、常に推定アドレス空間モードが使用されます。

3.

宣言: 5.9.2 節で示される要件に加えて、縮小された機能セットは、静的ストレージ期間を持つ const または constexpr として宣言されたデバイス関数内で odr-use のサポートを必要としません。

B.3.

互換性

さまざまな種類の相違を排除するため、縮小された機能セットと完全な機能セットの関係は、完全な機能セットが縮小された機能セットを包括するように定義されます。これは、縮小された機能セット向けに開発されたアプリケーションは、SYCL 縮小実装と SYCL 完全
実装の両方と互換性があることを意味します。

B.4.

適合性

これを仕様で定義する理由は、自社のプラットフォームで SYCL をサポートすることを望むハードウェア・ベンダーが、適合性にパスすることで SYCL サポートの実証を望むためです。ただし、適合性にパスするために、追加の開発工程が生じる必要としない機能を採用しなければならないのであれば、開発を躊躇するでしょう。
それぞれの機能セットには、適合性をパスする独自のルートがあり、SYCL の採用者は適合性をテストしたい機能セットを指定することができます。適合性テストスイートは、上記の機能セットがどのように区分されているかに応じて、テストスイートのテストを変更したり、無効にしたりできます。

付録 B 機能セット | 411

SYCL 2020 リビジョン 6 - C.1 SYCL アプリケーションとネイティブ・バックエンド・オブジェクトの相互運用性

付録 C OpenCL バックエンド仕様
この章では、SYCL の一般的なプログラミング・モデルが OpenCL にどのようにマッピングされているか、また、OpenCL バックエンド
用に記述された SYCL アプリケーションの相互運用性を確保するために、OpenCL 向けの SYCL 実装を提供するベンダーがどのように SYCL の一般的な相互運用性インターフェイスを実装しなければならないかを説明します。

C.1.

SYCL アプリケーションとネイティブ・バックエンド・オブ
ジェクトの相互運用性

SYCL アプリケーションの相互運用性をサポートする SYCL ランタイムクラスでは、SYCL バックエンド向けの SyclType に関連付けられた SYCL アプリケーションの相互運用性ネイティブ・バックエンド・オブジェクトのタイプとして、backend_traits::input_type とbackend_traits::return_type の特殊化を定義する必要があります。
SYCL アプリケーションの相互運用性向けのネイティブ・バックエンド・オブジェクトのタイプを表 190 に示します。

C.2.

カーネル関数とネイティブ・バックエンド・オブジェクトの相互運用性

カーネル関数の相互運用性をサポートする SYCL ランタイムクラスでは、backend_traits::return_type の特殊化は SYCL バックエン
ドの SyclType に関連付けられたカーネル関数の相互運用性ネイティブ・バックエンド・オブジェクトのタイプとして定義される必要があります。
カーネル関数の相互運用性向けのネイティブ・バックエンド・オブジェクトのタイプを表 186 に示します。
表 186. ネイティブ・バックエンド・オブジェクト・タイプのカーネル関数の相互運用性
SyclType

backend_return_t<backend::opencl, SyclType>accessor<T, Dims, Mode, target::device>__global T*

accessor<T, Dims, Mode, target::constant_buffer>__constant T*

accessor<T, Dims, Mode, target::local>__local T*

local_accessor<T, Dims>__local T*

sampled_image_accessor<T, 1, Mode,sampler_1dimage_pair_t

image_target::device>sampled_image_accessor<T, 2, Mode,sampler_2dimage_pair_t

image_target::device>sampled_image_accessor<T, 3, Mode,sampler_3dimage_pair_t

image_target::device>unsampled_image_accessor<T, 1, Mode,
image_target::device>

412 | 付録 C OpenCL バックエンド仕様

image1d_t

SYCL 2020 リビジョン 6 - C.3 参照セマンティクスによる相互運用構造オブジェクトの破棄

SyclType

backend_return_t<backend::opencl, SyclType>unsampled_image_accessor<T, 2, Mode,

image2d_t

image_target::device>unsampled_image_accessor<T, 3, Mode,

image3d_t

image_target::device>stream__global cl_char*device_event

event_tsampler_1dimage_pair_t、sampler_1dimage_pair_t および sampler_1dimage_pair_t タイプは、以下に示すように実装する必要があります。
1.

struct sampler_1dimage_pair_t {2.

sampler_t sampler;

3.
4.

image1d_t image;
}

5.
6.

struct sampler_2dimage_pair_t {7.

sampler_t sampler;

8.
9.

image2d_t image;
}

10.
11.

struct sampler_3dimage_pair_t {12.

sampler_t sampler;

13.
14.

C.3.

image3d_t image;}

参照セマンティクスによる相互運用構造オブジェクトの破棄

4.5.1.3 節で説明する SYCL バックエンド相互運用関数 make_* の 1 つを使用して構築された、4.5.2 節に示す参照セマンティクスを持つ SYCL クラスのインスタンスの最後のコピー破棄で、ベースとなるネイティブ・バックエンド・オブジェクトに必要な付加的なライフ
タイムに関連する操作が実行される可能性があります。
各 SYCL クラスの OpenCL SYCL バックエンドで実行される付加的な動作を表 187 に示します。
表 187. 参照セマンティクスを持つ相互運用構造オブジェクトのデストラクターの動作
SYCL オブジェクト

記述子の動作accessor

追加の動作はありません。

bufferclReleaseMemObject は 、 構 築 中 に 提 供 さ れ る ネ イ テ ィ ブ
cl_mem オブジェクトで呼び出されます。

context

clReleaseContext は 、 構 築 中 に 提 供 さ れ る ネ イ テ ィ ブ
cl_context オブジェクトで呼び出されます。

付録 C OpenCL バックエンド仕様 | 413

SYCL 2020 リビジョン 6 - C.4 OpenCL フレームワーク向けの SYCLSYCL オブジェクト

記述子の動作

deviceclReleaseDevice は、構築中に提供されるネイティブ cl_device
オブジェクトで呼び出されます。

event

clReleaseEvent は、構築中に提供されるネイティブ cl_event オ
ブジェクトで呼び出されます。

kernelclReleaseKernel は、構築中に提供されるネイティブ cl_kernel
オブジェクトで呼び出されます。

kernel_bundle

clReleaseProgram は 、 構 築 中 の 提 供 さ れ る ネ イ テ ィ ブ
cl_program オブジェクトで呼び出されます。

platform

追加の動作はありません。

queue

clReleaseCommandQueue は、構築中の提供されるネイティブ
cl_command_queue オブジェクトで呼び出されます。

sampled_image

clReleaseMemObject は 、 構 築 中 に 提 供 さ れ る ネ イ テ ィ ブ
cl_mem オブジェクトで呼び出されます。

unsampled_image

clReleaseMemObject は 、 構 築 中 に 提 供 さ れ る ネ イ テ ィ ブ
cl_mem オブジェクトで呼び出されます。

C.4.

OpenCL フレームワーク向けの SYCLSYCL フレームワークは、アプリケーションがホストと 1 つまたは複数の OpenCL デバイスを単一のヘテロジニアス並列コンピュー
ター・システムとして利用することを可能にします。フレームワークは次のコンポーネントを含みます。

• SYCL C++ テンプレート・ライブラリー: テンプレート・ライブラリーには、プログラミング・モデルをユーザーに提供する C++ テン
プレートとクラスが含まれます。SYCL キュー、バッファー、イメージなどのランタイムクラスの構築や、コンテキスト、プラット
フォーム、デバイス、プログラム・オブジェクトなどの OpenCL ランタイム・オブジェクトへのアクセスが可能です。

• SYCL ランタイム: SYCL ランタイムは、ベースとなる OpenCL 実装とのインターフェイスとなり、キュー内のコマンドのスケジュー
ル、ホストとデバイス間のデータ移動、コンテキスト、プログラム、カーネルのコンパイル、およびメモリー管理を行います。

• OpenCL 実装: SYCL システムは、ホストマシンに利用可能な 1 つ以上の OpenCL 実装が存在することを前提としています。
• SYCL デバイス・コンパイラー: SYCL デバイス・コンパイラーは、実行時に OpenCL デバイスで実行できる形式に SYCL カーネルをコンパイルします。SYCL 実装には、複数の SYCL デバイス・コンパイラーが存在する場合があります。コンパイルされた SYCL
カーネルの形式は定義されていません。SYCL デバイス・コンパイラーは、プログラムのホスト部分をコンパイルする場合としない
場合があります。
OpenCL バックエンドは、enum class backend の sycl::backend::opencl 値によって有効化されます。つまり、OpenCL バックエンド
がアクティブであると、sycl::is_backend_active<sycl::backend::opencl>::value の値は true になります。

C.5.

OpenCL 上での SYCL プログラミング・モデルの対応

SYCL プログラミング・モデルは、本来 OpenCL API の高レベルモデルとして設計されているため、OpenCL API における SYCL のマッ
ピングの大部分はシンプルです。

414 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.5 OpenCL 上での SYCL プログラミング・モデルの対応
OpenCL バックエンドが SYCL アプリケーションでアクティブである場合、利用可能なすべての OpenCL プラットフォームが SYCL プ
ラットフォームとしてエクスポートされます。
SYCL 実装が OpenCL デバイスでカーネルを実行する場合、OpenCL コマンドをエンキューしてデバイス内の処理要素で計算を実行することでこれを実現します。OpenCL 計算ユニット内の処理要素は、SIMD ユニット内の ALU (単一の命令ストリームを同調して実行)、独立した SPMD ユニット (各 PE が個別のプログラムカウンターを保持)、または 2 つを組み合わせて単一命令ストリームを実行できます。

C.5.1. バックエンド固有の情報記述子
一部の SYCL 情報記述子はバックエンドで定義されています。OpenCL バックエンドでは、これらの記述子は以下の表に示されるように、OpenCL プロパティーに直接マップされます。
表 188. SYCL 情報記述子の OpenCL プロパティーへのマップ
SYCL

OpenCL

info::platform::version

CL_PLATFORM_VERSION

info::device::version

CL_DEVICE_VERSION

C.5.2. OpenCL メモリーモデル
OpenCL プラットフォームで実行される SYCL デバイスのメモリーモデルは、準拠する OpenCL バージョンのメモリーモデルに従います。
グローバルメモリー、ローカルメモリーおよびプライベート・メモリーに加えて、OpenCL バックエンドでは、SYCL の定数メモリー空間を利用できます。

• 定数メモリーは、カーネルの実行中に定数が保持されるメモリー領域です。汎用アドレス空間へのポインターは、このメモリー領域のアドレスを指すことはできません。
カーネルで実行される work-item は、表 189 で示される SYCL と OpenCL 間のマッピングにより、4 つの異なるメモリー領域をアクセスできます。
表 189. SYCL メモリー領域の OpenCL メモリー領域へのマッピング
SYCL

OpenCLグローバル

グローバルメモリー定数定数メモリー

ローカル

ローカルメモリー

プライベートプライベート・メモリー

C.5.3. バッファー・コマンド・アクセサーの OpenCL インターフェイス
列挙子 target::constant_buffer は非推奨ですが、拡張機能として OpenCL バックエンドに残されています。これにより、SYCL カーネ
ル関数が OpenCL デバイスの定数メモリーを介してバッファーの内容にアクセスできるようになります。

付録 C OpenCL バックエンド仕様 | 415

SYCL 2020 リビジョン 6 - C.6 OpenCL API との相互運用性

C.5.4. SYCL アプリケーションによる OpenCL リソース管理
OpenCL では、開発者はデバイス上でコマンドを実行できるようにコンテキストを作成する必要があります。コンテキストの作成には、
プラットフォームとデバイスリストの選択が含まれます。SYCL には、コンテキスト、プラットフォーム、およびデバイスのすべてが存在しますが、ユーザーはそれらを直接指定するか、SYCL 実装で自動的に作成するかを選択できます。SYCL において、デバイスにワークを送信するために最小限必要なオブジェクトはキューです。キューには、プラットフォーム、デバイスおよびコンテキストへの参照が含まれます。
SYCL によって管理されるリソースを以下に示します。
1.

プラットフォーム: OpenCL のすべての機能はプラットフォームによって実装されます。プラットフォームは、特定のハード
ウェア・ベンダーのランタイムや、それを介してアクセス可能なデバイスと見なすことができます。一部のデバイスはベン
ダー固有のランタイムにのみアクセスできることから、複数のプラットフォームが存在する場合もあります。SYCL はユー
ザーのさまざまなプラットフォームを管理します。SYCL では、プラットフォームのリソースは sycl::platform オブジェクトを介してアクセスできます。

2.

コンテキスト: ユーザーが取得したすべての SYCL バックエンドのリソースは、コンテキストにアタッチされます。コンテキ
ストには、ホストが利用できるデバイスのコレクションが含まれ、デバイス間で共有されるメモリー・オブジェクトを管理します。コンテキスト内のデバイス間でのデータ移動は効率的で、ベースとなる OpenCL ランタイムによって隠匿される場合がありますが、コンテキスト間のデータ移動にはホストの関与が必要となることがあります。特定のコンテキストは、単一のプラットフォームが所有するデバイスのみを包括できます。SYCL では、コンテキストのリソースは sycl::context オブジェ
クトを介してアクセスできます。

3.

デバイス: プラットフォームは、カーネルを実行する 1 つ以上のデバイスを提供します。SYCL では、デバイスは sycl::device
オブジェクトを介してアクセスできます。

4.

カーネルバンドル: SYCL カーネルの実装データを格納する OpenCL オブジェクトです。これらのオブジェクトは、SYCL における高度な利用でのみ必要であり、sycl::kernel_bundle クラスにカプセル化されています。

5.

キュー: SYCL カーネルはコマンドキューを実行します。ユーザーは、関連するコンテキスト、プラットフォーム、およびデバイスを参照するキューを作成する必要があります。コンテキスト、プラットフォーム、およびデバイスは自動的に選択される
か、ユーザーが指定できます。SYCL では、コマンドキューは sycl::queue オブジェクトを介してアクセスできます。

C.6.

OpenCL API との相互運用性

SYCL 用の OpenCL バックエンドは、SYCL と OpenCL カーネルおよび API 間との最大限の互換性を保証します。これには、C++ で記述される SYCL カーネルのサポートに加え、各種機能を備えたデバイスのサポートと、OpenCL C 言語のそれぞれのバージョンのサポートが含まれます。
SYCL context や SYCL queue などの OpenCL 不透過 (opaque) タイプをカプセル化する SYCL ランタイムクラスは、OpenCL 不透
過タイプのインスタンスを受け取る相互運用コンストラクターを提供する必要があります。OpenCL オブジェクトが参照カウンターをサポートする場合、それらのコンストラクターは、OpenCL リソースの参照カウントをインクリメントするため、そのインスタンスを保持する必要があります。同様に、参照カウントされた OpenCL 不透過 (opaque) タイプとカプセル化する SYCL ランタイムのデストラク
ターは、そのインスタンスを解放して OpenCL リソースの参照カウントをデクリメントする必要があります。OpenCL platform_id は参照カウントされないため、カプセル化する SYCL platform クラスはこの OpenCL リソースを保持も解放もしません。
OpenCL の不透過タイプをカプセル化する SYCL ランタイムクラスのインスタンスは、相互運用性コンストラクターを使用して構築された場合を除き、OpenCL タイプのインスタンスをいくつでもカプセル化できます。相互運用性コンストラクターを使用して構築された場合は、OpenCL タイプのインスタンスを 1 つだけカプセル化できます。

416 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.6 OpenCL API との相互運用性
OpenCL の不透過タイプをカプセル化する SYCL ランタイムクラスの存続期間と、get_native() フリー関数を介して取得された不透過タイプのインスタンスは、OpenCL 参照カウントを適切に使用することを考慮すると、どちらの方向にも関連付けできません。例えば、
ユーザーが SYCL queue インスタンスから cl_command_queue インスタンスを取得して、すぐに SYCL queue インスタンスを破棄すると、cl_command_queue インスタンスは引き続き有効のままです。または、ユーザーが cl_command_queue インスタンスから
SYCL queue インスタンスを構築して、すぐに cl_command_queue インスタンスを解放すると、SYCL queue インスタンスは引き続
き有効のままです。
OpenCL の不透過タイプをカプセル化する SYCL ランタイムクラスは、SYCL ランタイム外で OpenCL 参照カウントの不適切な使い方に対し責任を持たないことに注意してください。例えば、ユーザーが SYCL queue インスタンスから cl_command_queue インスタンスを取得し、事前に保持することなく cl_command_queue インスタンスを複数回解放した場合、cl_command_queue インスタン
スが取得された SYCL queue インスタンスは未定義となります。
相互運用性コンストラクターで構築された SYCL buffer や SYCL image クラス・テンプレートのインスタンスは、SYCL buffer や
SYCL image のインスタンスが有効である限り、通常の SYCL セマンティクスを実現するため、cl_mem から SYCL ランタイム内の別のメモリー割り当てに自由にコピーできます。
表 190 は、SYCL オブジェクトの SYCL アプリケーションの OpenCL ネイティブタイプへの関連付けを示します。
表 190. OpenCL バックエンドの SYCL オブジェクトごとのネイティブタイプのリスト
SyclType

platformbackend_input_t< backend_return_t
backend::opencl,<backend::opencl,

SyclType>

SyclType>

cl_platform_id

cl_platform_id

説明

SYCL プラットフォーム・オブジェクトは、 OpenCL プラット
フォーム id をカプセル化します。

devicecl_device_id

cl_device_id

SYCL デバイス・オブジェクトは、OpenCL デバイス・オブジェク
トをカプセル化します。

context

cl_context

cl_context

SYCL コンテキスト・オブジェクトは、OpenCL コンテキスト・オブジェクトをカプセル化します。

queue

kernelcl_command_que

cl_command_que

SYCL キュー・オブジェクトは、OpenCL キュー・オブジェクトをカueue

プセル化します。

cl_kernel

cl_kernel

SYCL カーネル・オブジェクトは、OpenCL カーネル・オブジェク
トをカプセル化します。

template

cl_program<bundle_state

std::vector<cl_pro SYCL カーネルバンドルは、1 つ以上の OpenCL プログラム・オ
gram>
ブジェクトをカプセル化できます。また、適切な kernel オブジェ

State>

クトを使用して取得できる OpenCL カーネル・オブジェクトをカ

kernel_bundle

プセル化できます。

<State>event

std::vector<cl_eve

std::vector<cl_ev

SYCL イベントは、1 つまたは複数の OpenCL イベントをカプ

nt>

ent>

セル化できます。これは、SYCL イベントが完了するために満たす必要がある、同一コンテキストまたは異なるコンテキスト間の多くの依存関係を表します。

buffercl_memstd::vector<cl_me

OpenCL メモリー・オブジェクトを含む SYCL バッファーは、同m>

じコンテキストまたは異なるコンテキストで複数の cl_mem オ
ブジェクトを処理できます。相互運用インターフェイスは、SYCL
ランタイムでアクティブなバッファーのリストを返します。

付録 C OpenCL バックエンド仕様 | 417

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス

SyclType

backend_input_t< backend_return_t

sampled_image

説明backend::opencl,<backend::opencl,

SyclType>

SyclType>cl_memstd::vector<cl_me

OpenCL イメージ・オブジェクトを含む SYCL サンプルイメージ

m>は、同じまたは異なる OpenCL コンテキストで、複数のベースとなる cl_mem オブジェクトを同時に処理できます。相互運用イ
ンターフェイスは、SYCL ランタイムでアクティブなイメージのリストを返します。

unsampled_image

cl_memstd::vector<cl_me

OpenCL サンプル・オブジェクトを含む SYCL 非サンプルイm>

メージは、同じコンテキストまたは異なるコンテキストで複数のベースとなる cl_mem オブジェクトを処理できます。相互運
用インターフェイスは、SYCL ランタイムでアクティブなイメージのリストを返します。

SYCL カーネル内で、SYCL API は OpenCL デバイスタイプとの相互運用性を提供します。表 191 にカーネルタイプのマッピングを示します。
表 191. カーネルコードの SYCL オブジェクトごとのネイティブタイプのリスト
OpenCL の SYCL カーネル・ネイティブ・タイプ

説明

multi_ptr::get_decorated()

複数ポインター・オブジェクト・タイプに対応する OpenCL アドレ
ス空間内のポインターを返します。

バッファーやイメージが複数の OpenCL デバイスに割り当てられている場合にそれらのデバイスが個別のコンテキストにある、オブジェクトがデバイスでアクティブに利用されるかどうかに応じて、複数の cl_mem オブジェクトがメモリー・オブジェクトに割り当てられることがあります。
OpenCL C 関数修飾子 __kernel とアクセス修飾子 __read_only、__write_only、および __read_write は、キーワードにより SYCL では公開されませんが、代わりにアクセサー内の SYCL パラメーターの受け渡しシステムにカプセル化されます。これらの修飾子と同等の OpenCL 機能を SYCL で実現することを望むユーザーは、同等のセマンティクスを持つ SYCL アクセサーを使用してください。
事前に構築された OpenCL ライブラリーに含まれる OpenCL C 関数は、extern "C" 関数として定義でき、OpenCL プログラムは外部関数を使用するカーネルを含むすべての SYCL プログラムに対しリンクする必要があります。この場合、使用されるデータタイプは、表193 で定義される相互運用性エイリアスに準拠しなければなりません。

C.7.

プログラミング・インターフェイス

次のセクションでは OpenCL 固有の ＡＰＩ について説明します。

C.7.1. OpenCL オブジェクトから SYCL オブジェクトを構築
OpenCL バックエンドは、4.5.1.3 節で定義される make_{sycl_class} テンプレート関数の以下に示す特殊化を提供します。これらの関数は、sycl 名前空間にあります。

418 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス

OpenCL 相互利用関数

説明

context make_context(

4.5.1 節で説明される要件に従って、OpenCL cl_context から

const cl_context& clContext,

SYCL context インスタンスを構築します。

const async_handler& asyncHandler = {})event make_event(const std::vector<cl_event >&clEvent,4.5.1 節で説明される要件に従って、OpenCL cl_event オブジェ
クトのベクトルから SYCL event インスタンスを構築します。

const context& syclContext)
device make_device(
const cl_device_id& clDeviceId)
platform make_platform(
const cl_platform_id& clPlatformId)
queue make_queue(

4.5.1 節で説明される要件に従って、OpenCL cl_device_id から
SYCL device インスタンスを構築します。
4.5.1 節で説明される要件に従って、OpenCL cl_platform_id から SYCL platform インスタンスを構築します。
4.5.1 節 で 説 明 さ れ る 要 件 に 従 っ て 、 OpenCL

const cl_command_queue& clQueue,

cl_command_queue から オプション async_handler を使用しconst context& syclContext,て SYCL queue インスタンスを構築します。

const async_handler& asyncHandler = {})template <typename T, int Dimensions = 1,
typename AllocatorT =buffer_allocator<std::remove_const _t<T>>>buffer<T, Dimensions, AllocatorT> make_buffer(const cl_mem& clMemObject,
const context& syclContext,
event availableEvent)

Dimensions == 1 の場合にのみ利用できます。
4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL
buffer インスタンスを構築します。構築される SYCL buffer クラス・テンプレートのインスタンスは、SYCL event パラメーター、
cl_mem インスタンスを使用する準備ができたことを通知する
availableEvent を待機しなければなりません。SYCL context パ
ラメーター、syclContext はメモリー・オブジェクトに関連付けられたコンテキストです。

template <typename T, int Dimensions = 1,
typename AllocatorT =buffer_allocator<std::remove_const _t<T>>>buffer<T, Dimensions, AllocatorT> make_buffer(

Dimensions == 1 の場合にのみ利用できます。
4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL
buffer インスタンスを構築します。

const cl_mem& clMemObject,
const context& syclContext)
template <int Dimensions = 1,

4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL

typename AllocatorT = image_allocator>

sampled_image インスタンスを構築します。構築される SYCL

sampled_image<Dimensions, AllocatorT>

image クラス・テンプレートのインスタンスは、SYCL event パラ

make_sampled_image(

メーター、cl_mem インスタンスを使用する準備ができたことを

const cl_mem& clMemObject,

通知する availableEvent を待機しなければなりません。SYCL

const context& syclContext,

context パラメーター、syclContext はメモリー・オブジェクトに

event availableEvent)

関連付けられたコンテキストです。

template <int Dimensions = 1,

4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL

typename AllocatorT = image_allocator>

sampled_image インスタンスを構築します。SYCL context パラ

sampled_image<Dimensions, AllocatorT>

メーター、syclContext はメモリー・オブジェクトに関連付けられ

make_sampled_image(たコンテキストです。

const cl_mem& clMemObject,
const context& syclContext)

付録 C OpenCL バックエンド仕様 | 419

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス

OpenCL 相互利用関数

説明

template <int Dimensions = 1,

4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL

typename AllocatorT = image_allocator>

unsampled_image イ ン ス タ ン ス を 構 築 し ま す 。 構 築 さ れ る

unsampled_image<Dimensions, AllocatorT>SYCL image クラス・テンプレートのインスタンスは、SYCL event

make_unsampled_image(

パラメーター、cl_mem インスタンスを使用する準備ができたこ

const cl_mem& clMemObject,とを通知する availableEvent を待機しなければなりません。

const context& syclContext,

SYCL context パラメーター、syclContext はメモリー・オブジェ

image_sampler syclImageSampler,
event availableEvent)template <int Dimensions = 1,
typename AllocatorT = image_allocator>

クトに関連付けられたコンテキストです。

4.5.1 節で説明される要件に従って、OpenCL cl_mem から SYCL
unsampled_image インスタンスを構築します。

unsampled_image<Dimensions, AllocatorT>
make_unsampled_image(
const cl_mem& clMemObject,
const context& syclContext,
image_sampler syclImageSampler)kernel make_kernel(const cl_kernel& clKernel,
const context& syclContext);

OpenCL カーネル・オブジェクトから SYCL kernel インスタンスを構築します。

template <bundle_state State>

4.5.1 節で説明される要件に従って、syclContext 内のデバイスのkernel_bundle<State>

OpenCL cl_program から SYCL kernel_bundle インスタンス

make_kernel_bundle(を構築します。SYCL context は、OpenCL プログラム・オブジェク

const cl_program& clProgram,トに関連付けられている同じベースの ＯｐｅｎＣＬ コンテキストをconst context& syclContext)

表現する必要があります。
state は期待される kernel_bundle の状態を指定します。kernel_
bundle 状 態 と OpenCL プ ロ グ ラ ム 状 態 (CL_PROGRAM_
BINARY_TYPE) 間のマッピングは次のようになります。

• bundle_state::input CL_PROGRAM_BINARY_TYPE_NONE• bundle_state::object CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECTまたは CL_PROGRAM_BINARY_TYPE_INTERMEDIATE
または CL_PROGRAM_BINARY_TYPE_LIBRARY• bundle_state::executable CL_PROGRAM_BINARY_TYPE_EXECUTABLE
OpenCL プログラムの内部状態と state が一致しない場合、カーネルバンドルは必要に応じてコンパイルおよびリンクされます。
OpenCL プログラムが実行可能バイナリーであっても、指定された
state が bundle_state::executable ではない場合、errc::invalid エ
ラ ー コ ー ド の 例 外 が ス ロ ー さ れ ま す 。 指 定 さ れ た state はbundle_state::input ですが、OpenCL プログラムがすでにバイナ
リーに関連付けられている場合は、errc::invalid エラーコードの例
外がスローされます。
SYCL バックエンドによってエラーが発生した場合、errc::build
エラーコードの例外をスローします。

420 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス

C.7.2. 拡張クエリー
OpenCL バックエンドを備えたプラットフォームとデバイスは、拡張機能をサポートする場合があります。利便性のため、プラットフォー
ムまたはデバイスでサポートされる拡張機能は sycl::opencl 名前空間で提供される次の関数で照会できます。

拡張クエリー

説明bool has_extension(

syclPlatform に関連付けられた OpenCL プラットフォームがconst sycl::platform& syclPlatform,

extension によって識別される拡張機能をサポートしている場

const std::string& extension)

合 は true を 返 し ま す 。 そ れ 以 外 は false を 返 し ま す 。
syclPlatform.get_backend() != sycl::backend::opencl である場 合 、 errc::backend_mismatch エラ ー コ ー ド で 例 外を ス
ローします。

bool has_extension(

syclDevice に関連付けられた OpenCL デバイスが extension

const sycl::device& syclDevice,

によって識別される拡張機能をサポートしている場合は true を

const std::string& extension)

返 し ま す 。 そ れ 以 外 は

false

を 返 し ま す 。

syclDevice.get_backend() != sycl::backend::opencl である
場合、errc::backend_mismatch エラーコードで例外をスローします。

C.7.3. 参照カウント
大部分の OpenCL オブジェクトは参照カウントされます。SYCL 一般プログラミング・モデルでは、ネイティブ・オブジェクトが参照カウントされる必要はありません。ただし、利便性のため次の関数が sycl::opencl 名前空間で提供されています。

参照カウント説明

template <typename openCLT>

指定されたオブジェクトの参照カウントを返します。

cl_uint get_reference_count(openCLT obj)

C.7.4. エラーと制限
ト リ ガ ー さ れ た 例 外 に 関 連 す る OpenCL エ ラ ー が 発 生 し て い る 場 合 、 OpenCL エ ラ ー コ ー ド は フ リ ー 関 数 cl_int
sycl::opencl::get_error_code(sycl::exception&) で取得できます。トリガーされた例外に関連する OpenCL エラーが発生していない
場合、OpenCL エラーコードは CL_SUCCESS になります。

C.7.5. カーネルバンドルとの相互運用性
OpenCL では、nd-range でエンキューされたカーネル関数はすべて cl_kernel で表現され、clBuildProgram、clCompileProgram お
よび clLinkProgram.cl_program を使用した cl_program 介してコンパイルおよびリンクする必要があります。
OpenCL SYCL バックエンドでは、カーネルバンドルによって詳細が抽象化され、すべての SYCL カーネル関数を含む kernel_bundle
オブジェクトは、フリー関数 get_kernel_bundle で取得されます。
OpenCL SYCL バックエンド仕様には、ＯｐｅｎＣＬ 固有のオブジェクトからカーネルバンドルを構築する際に便利な機能を提供するフリー関数があります。

付録 C OpenCL バックエンド仕様 | 421

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス
1.

namespace sycl::opencl {2.
3.

template <bundle_state State>4.

kernel_bundle<State> create_bundle(const context& ctxt,

5.

const std::vector<device>& devs,

6.

const std::vector<cl_program>& clPrograms);

7.
8.

kernel_bundle<bundle_state::executable>

9.

create_bundle(const context& ctxt, const std::vector<device>& devs,

10.

const std::vector<cl_kernel>& clKernels);

11.
12.

} // namespace sycl::opencl

1.

template <bundle_state State>2.

kernel_bundle<State> create_bundle(const context& ctxt,

3.

const std::vector<device>& devs,

4.

const std::vector<cl_program>& clPrograms)1.

前提条件: ctxt で指定されるコンテキストは、OpenCL SYCL バックエンドに関連付けられている必要があります。devs のすべてのデバイス、および clPrograms のすべての OpenCL デバイスは ctxt に関連付けられなければなりません。
効果: OpenCL プログラムのリストから指定された bundle_state のカーネルバンドルを構築し、必要な OpenCL API を呼び出して syclContext で指定されたコンテキストに関連付けます。規則が clPrograms 内のすべての OpenCL プログ
ラムに適用されることを除き、単一の OpenCL プログラムで make_kernel_bundle を呼び出すのと同じ規則に従います。
要求された State に応じて、複数のプログラムが単一のプログラムにリンクされます。構築された kernel_bundle は、与えられたすべての OpenCL プログラムを保持し、破棄されるときにそれらを解放します。
スロー: OpenCL API を呼び出してエラーが発生する場合、errc::build エラーコードの例外をスローします。

1.

kernel_bundle<bundle_state::executable>2.

create_bundle(const context& ctxt, const std::vector<device>& devs,

3.

const std::vector<cl_kernel>& clKernels)

1.

前提条件: ctxt で指定されるコンテキストは、OpenCL SYCL バックエンドに関連付けられている必要があります。devs のすべてのデバイスは、ctxt に関連付けられている必要があります。clKernels のすべての OpenCL デバイスは ctxt に関連付けられなければなりません。
効果: OpenCL カーネルのリストから実行可能な カーネルバンドルを構築し、必要な OpenCL API を呼び出してsyclContext で指定されたコンテキストに関連付けます。cl_kernel オブジェクトは異なる cl_program オブジェクトに関連付けられている可能性があり、カーネルバンドルはそれらすべてをカプセル化します。
スロー: OpenCL API を呼び出してエラーが発生する場合、errc::build エラーコードの例外をスローします。

C.7.6. カーネルとの相互運用性
kernel_bundle オブジェクトには、単独または複数の OpenCL プログラムと 1 つまたは複数の OpenCL カーネルが含まれます。
kernel_bundle::get_kernel を呼び出すと、kernel を実行しても SYCL カーネル関数を使用しない、parallel_for などの任意のカーネ
ル起動コマンドで呼び出し可能な kernel オブジェクトが返されます。
make_kernel 呼び出しは clRetainKernel 呼び出しをトリガーして、結果の kernel オブジェクトは破棄される際に clReleaseKernelを呼び出す必要があります。

422 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイス
C.7.5 節で説明するように、フリー関数 create_bundle を呼び出して、作成済みの OpenCL cl_kernel オブジェクトからカーネルバン
ドルを作成することもできます。
OpenCL C カーネルのカーネル引数は、kernel オブジェクトを作成する前に設定するか、handler クラスの set_arg または set_args
メンバー関数を呼び出すことで設定できます。
kernel オブジェクトを作成する前にカーネル引数が設定されている場合、SYCL ランタイムはそれらの引数データを管理する責任はありません。

C.7.7. OpenCL カーネル規約と SYCLOpenCL と SYCL は、単位ストライド次元の方向が異なります。SYCL は C++ の規則に準拠します。つまり、コードを SYCL に移植する
際は、パフォーマンスの観点を理解することが重要です。少なくともデータの場合、SYCL (3.11.1 節) と OpenCL の線形方程式には、単位ストライド次元が暗黙的に含まれます。SYCL では、C++ 配列のインデックスの順序 arr[a][b][c] に合わせて、カーネルの起動に使用されるレンジ・コンストラクターの次元順序 (range<3> R{a,b,c} など) や、カーネル内のレンジと ID のクエリーは C++ の多次元イン
デックスのオペレーターと同じ順序になります (右のユニットストライド)。
OpenCL 相互運用カーネルを呼び出す parallel_for でグローバルサイズやローカルサイズに range を指定すると (cl_kernel を介して)、SYCL のレンジの最大次元が OpenCL カーネル内で最小次元にマッピングされます。
このステートメントは、OpenCL の clEnqueueNDRangeKernel などベースとなるエンキュー操作と、OpenCL カーネル内の ID およびサイズクエリーの両方に適用されます。例えば、3D グローバルレンジは SYCL では次のように指定されます。
range<3> R{r0,r1,r2};
次の clEnqueueNDRangeKernel global_work_size 引数にマップします。
size_t cl_interop_range[3] = {r2,r1,r0};
同様に、SYCL では次のように 2D グローバルレンジを指定します。
range<2> R{r0,r1};
次の clEnqueueNDRangeKernel global_work_size 引数にマップします。
size_t cl_interop_range[2] = {r1,r0};
SYCL の最上位次元から OpenCL の最下位次元へのマッピングは、SYCL の明示的なメモリー操作を clEnqueueCopyBufferRect のような OpenCL API にマッピングする場合など、多次元構造をマッピングする必要があるすべての操作に適用されます。
Work-item と work-group ID および range クエリーには、SYCL と OpenCL 間の単位ストライド次元の反転規則は同じです。例えば、
3、2、または 1 次元の SYCL グローバルレンジでは、OpenCL と SYCL カーネルコードのクエリーは、表 192 のようにレンジに関連します。「SYCL カーネルクエリー」のカラムは SYCL 定義のカーネルに適用され、「OpenCL カーネルクエリー」のカラムは OpenCL 相
互運用機能を介して定義されたカーネルに適用されます。
表 192. SYCL でエンキューされた 3 次元グローバル range から OpenCL および SYCL クエリーへのレンジマッピングの例
SYCL カーネルクエリー

OpenCL カーネルクエリー

戻り値

エンキューされた 3D SYCL グローバル range<3> R{r0、r1、r2} の range
nd_item::get_global_range(0) / item::get_range(0)get_global_size(2)r0nd_item::get_global_range(1) / item::get_range(1)get_global_size(1)r1

付録 C OpenCL バックエンド仕様 | 423

SYCL 2020 リビジョン 6 - C.7 プログラミング・インターフェイスSYCL カーネルクエリー

OpenCL カーネルクエリー

戻り値

nd_item::get_global_range(2) / item::get_range(2)get_global_size(0)r2nd_item::get_global_id(0) / item::get_id(0)get_global_id(2)range 0 の値..(r0-1)}

nd_item::get_global_id(1) / item::get_id(1)get_global_id(1)range 0 の値..(r1-1)}

nd_item::get_global_id(2) / item::get_id(2)get_global_id(0)range 0 の値..(r2-1)}

エンキューされた 2D SYCL グローバル range<2> R{r0、r1} の range
nd_item::get_global_range(0) / item::get_range(0)get_global_size(1)r0nd_item::get_global_range(1) / item::get_range(1)get_global_size(0)r1nd_item::get_global_id(0) / item::get_id(0)get_global_id(1)range 0 の値..(r0-1)}

nd_item::get_global_id(1) / item::get_id(1)get_global_id(0)range 0 の値..(r1-1)}

エンキューされた 1D SYCL グローバル range<1> R{r0} の range
nd_item::get_global_range(0) / item::get_range(0)get_global_size(0)r0nd_item::get_global_id(0) / item::get_id(0)get_global_id(0)range 0 の値..(r0-1)}

C.7.8. データタイプ
OpenCL C 言語標準の 6.11 節では、ビルトイン・スカラー・データ・タイプが定義されており、これには ISO C++ で保証されるものに加え、サイズと符号に関して追加の要件があります。相互運用性と移植性を考慮して、SYCL は cl_ プリフィクスを使用して、sycl::opencl
名前空間の C++ タイプへのエイリアスを定義します。それらのエイリアスは、表 193 に示します。
表 193. SYCL OpenCL バックエンドによるスカラー・データ・タイプのエイリアスサポート
スカラー・データ・タイプのエイリアス

説明

cl_booltrue または false のいずれかである条件付きデータタイプへのエイリ
アス。true は整数定数 1 に展開され、false は整数定数 0 に展開されます。

cl_charC++ コア言語で定義される符号付き 8 ビット整数のエイリアス。

cl_ucharC++ コア言語で定義される符号なし 8 ビット整数のエイリアス。

cl_short

C++ コア言語で定義される符号付き 16 ビット整数のエイリアス。

cl_ushort

C++ コア言語で定義される符号なし 16 ビット整数のエイリアス。

cl_intC++ コア言語で定義される符号付き 32 ビット整数のエイリアス。

cl_uint

C++ コア言語で定義される符号なし 32 ビット整数のエイリアス。

cl_longC++ コア言語で定義される符号付き 64 ビット整数のエイリアス。

cl_ulongC++ コア言語で定義される符号なし 64 ビット整数のエイリアス。

424 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.8 プリプロセッサー・ディレクティブとマクロ

スカラー・データ・タイプのエイリアス

説明

cl_float

32 ビット浮動小数点のエイリアス。float データタイプは、IEEE 754
単精度ストレージ形式に準拠する必要があります。

cl_double

64 ビット浮動小数点のエイリアス。double データタイプは、IEEE
754 倍精度ストレージ形式に準拠する必要があります。

cl_half

16 ビット浮動小数点のエイリアス。半精度データタイプは、IEEE 7542008 半精度ストレージ形式に準拠する必要があります。このタイプを使用するカーネルは、5.7 節で説明されるように、aspect::fp16 を持
つデバイスでのみサポートされます。

C.8.

プリプロセッサー・ディレクティブとマクロ• SYCL_BACKEND_OPENCL は、SYCL アプリケーションの構築中のに OpenCL SYCL バックエンドがアクティブである場合 1 に置き換えられます。

C.8.1. OpenCL C ライブラリーとのオフラインリンク
SYCL は、オフラインコンパイル中または SYCL アプリケーションの SYCL ランタイムによるオフラインコンパイルで、SYCL カーネル
関数と OpenCL C ライブラリーとのリンクをサポートします。
OpenCL C カーネル関数とのオフラインリンクはオプション機能であり未指定です。OpenCL C カーネル関数とのオフラインリンクに
は 、 SYCL kernel_bundle ク ラ ス を 使 用 し て OpenCL C ソ ー ス を コ ン パ イ ル し ま す 。 compile_with_source ま た はbuild_with_source メンバー関数を使用します。
オフラインまたはオンラインコンパイルでリンクされる OpenCL C 関数は、extern "C" 関数として宣言する必要があります。これらの関数宣言の関数パラメーターは、OpenCL C 相互運用性エイリアスとして定義する必要があります。multi_ptr クラスの pointer、vec
クラス・テンプレートの vector_t、および表 193 に示すスカラー・データ・タイプのエイリアス。

C.9.

非コア OpenCL 機能のサポート

OpenCL コア機能に加え、SYCL は khr 拡張を介して OpenCL の機能を提供する OpenCL 拡張機能もサポートします。
一部の拡張機能は SYCL インターフェイス内でネイティブにサポートされますが、その一部は OpenCL 相互運用インターフェイスを介してのみ利用できます。これには、ネイティブ拡張に必要な SYCL インターフェイスが利用可能である必要があります。ただし、それぞれの 拡 張 機 能 が 実 行 中 の SYCL device で サ ポ ー ト さ れ な い場 合 、 SYCL ラ ン タイ ム は errc::feature_not_supported ま た は
errc::kernel_not_supported エラーコードで例外をスローする必要があります。
OpenCL バックエンドは、sycl::aspect 列挙タイプを介して SYCL アプリケーションが khr を利用できるようにします。従って、アプリ
ケーションは device::has() または platform::has() メンバー関数を呼び出すことで、それらの khr 拡張機能を照会できます。
すべての OpenCL 拡張機能は、OpenCL 相互運用インターフェイスを介して利用できますが、コア SYCL API で利用できるものもあります。表 194 に詳細を示します。表 194 は、各 OpenCL 拡張機能名から関連する SYCL デバイス aspect が利用できるマッピングも示しています。

付録 C OpenCL バックエンド仕様 | 425

SYCL 2020 リビジョン 6 - C.10 OpenCL 機能の SYCL への対応
表 194. OpenCL 1.2 拡張の SYCL サポート
SYCL アスペクト

OpenCL 拡張

コア SYCL API

aspect::atomic64

cl_khr_int64_base_atomics

はいaspect::atomic64

cl_khr_int64_extended_atomics

はいaspect::fp16

cl_khr_fp16

はい-cl_khr_3d_image_writes

はい-cl_khr_gl_sharing

いいえ-

cl_apple_gl_sharing

いいえ-

cl_khr_d3d10_sharing

いいえ-

cl_khr_d3d11_sharing

いいえ

C.9.1. 半精度浮動小数点
半精度スカラー・データ・タイプ half と半精度ベクトル・データ・タイプ half1、half2、half3、half4、half8 および half16 は、コンパイル時に使用可能でなければなりません。ただし、このタイプを使用するカーネルは、5.7 節で説明されるように、aspect::fp16 を持つデバ
イスでのみサポートされます。
半精度タイプの変換規則は、『OpenCL 1.2 拡張仕様』の 9.5.1 節と同じ規則に従います。
半精度タイプの数学関数は、『OpenCL 1.2 拡張仕様』の 9.5.2、9.5.3、9.5.4、9.5.5 節と同じ規則に従います。ULP (Unit in the Last
Place) で許容されるエラーは、『OpenCL 1.2 仕様』の表 6.9 に相当する 8192 未満です。

C.9.2. 3D イメージ・メモリー・オブジェクトへの書き込み
SYCL の unsampled_image_accessor クラスは、３D イメージ・メモリー・オブジェクトを書き込むメンバー関数をサポートしますが、この機能は、拡張 cl_khr_3d_image_writes がデバイスでサポートされる場合にのみデバイスで許可されます。

C.9.3. OpenGL との相互運用性
SYCL と OpenGL 間の相互運用性は SYCL インターフェイスで直接提供されませんが、SYCL OpenCL 相互運用インターフェイスを介して実現できます。

C.10. OpenCL 機能の SYCL への対応
このセッションでは、OpenCL 機能および同様の機能を提供するコア SYCL 仕様機能との対応について説明します。このセッションの内容は規範的ではありません。

426 | 付録 C OpenCL バックエンド仕様

SYCL 2020 リビジョン 6 - C.10 OpenCL 機能の SYCL への対応

C.10.1. Work-item 関数『OpenCL 1.2 仕様』の 6.12.1 節の表 6.7 は、OpenCL カーネルで実行中の work-item に関連する各種情報を通知する work-item
関数を定義します。SYCL は、4.9.1.4 節、4.9.1.5 節および 4.9.1.7 節で定義される項目とグループクラスを通して同等の機能を提供します。

C.10.2. ベクトルデータのロードとストア関数『OpenCL 1.2 仕様』の 6.12.7 節で定義される OpenCL 関数の機能は、4.14.2 節の vec クラスを介して SYCL で使用できます。

C.10.3. 同期関数
SYCL では、OpenCL 同期関数は nd_item クラス (4.9.1.5 節) を介して使用できます。これは、ローカルまたはグローバルアドレス空間の work-item に適用されるためです。表 119 を参照してください。

C.10.4. printf 関数
printf 関数は、すべての SYCL クラスとプリミティブを stdout に出力する機能があり、『OpenCL 1.2 仕様』の 6.12.13 節で定義される機能を提供する stream クラス (4.16 節) によってカバーされます。

付録 C OpenCL バックエンド仕様 | 427

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点

付録 D 前バージョンからの変更点
D.1.

SYCL 1.2.1 から SYCL 2020 への変更点

SYCL ラ ン タ イ ム は 、 4.3 節 で 説 明 す る よ う に 、 #include <Cl/sycl.hpp> で 定 義 さ れ る cl::sycl 名 前 空 間 か ら 、 #include<sycl/sycl.hpp> で提供される sycl 名前空間に移動されています。古いヘッダーは、SYCL 1.2.1 を使用するアプリケーションとの互換性のため引き続き使用できます。
SYCL 仕様は、3.9.1 節で説明されるように、C++17 コア言語をベースにしています。クラス・テンプレート引数のデダクション向けのガイドなど、C++17 の機能が仕様で有効になっています。
カーネル呼び出し時に渡されるラムダ関数の命名はオプションになりました。
以下は、バッファー、イメージ、およびアクセサーの変更です。

• image ク ラ ス は 削 除 さ れ ま し た 。 サ ン プ リ ン グ さ れ た イ メ ー ジ と サ ン プ リ ン グ さ れ て い な い イ メ ー ジ を 表 す 新 し い
unsampled_image と sampled_image が追加されました。sampler クラスが削除され、新しい image_sampler 構造体に置き換えられました。

• イメージアレイのサポートが削除されました。
• タイプ名 access::target は非推奨となり、タイプ target に置き換えられました。
• タイプ名 access::mode は非推奨となり、タイプ access_mode に置き換えられました。
• accessor ターゲット名 target::global_buffer は、非推奨となり target::device に置き換えられました。
• accessor タ ー ゲ ッ ト target::host_buffer は 非 推 奨 と な り ま し た 。 同 等 の 機 能 を 提 供 す る 新 た な ア ク セ サ ー ク ラ ス
host_accessor が追加されました。

• target::host_buffer タイプの accessor を返す buffer メンバー関数は非推奨となりました。host_accessor を返す新しいメンバー関数 get_host_access() が追加されました。

• buffer クラスには、各種パラメーターを持つ accessor の構築を可能にする get_access() メンバー関数に新しい可変引数オーバーロードがあります。

• accessor タ ー ゲ ッ ト target::local の サ ポ ート は 非 推 奨 とな り ま し た 。 同 等の 機 能を 提供 す る新 た な ア クセ サ ー クラス
local_accessor が追加されました。

• accessor ターゲット target::image と target::host_image のサポートが削除されました。サンプルイメージと非サンプルイメー
ジ向けの次の新しいアクセサークラスが追加されました : sampled_image_accessor、host_sampled_image_accessor、
unsampled_image_accessor および host_unsampled_image_accessor。

• 新しい accessor ターゲット target::host_task が追加され、ホストタスクから buffer にアクセスできるようになりました。
• accessor モード access_mode::discard_write と access_mode::discard_read_write のサポートは非推奨になりました。プロ
パティー・リストでアクセサーを構築できるようになり、新しいプロパティー property::no_init が同様の機能を提供します。

• accessor モード access_mode::atomic と、atomic クラスのインスタンスを返すメンバー関数のサポートは廃止され、代わりに新しい atomic_ref クラスを使用します。

• accessor テンプレート・パラメーター isPlaceholder のサポートは非推奨となり、このパラメーター値はアクセサーがプレースホルダーであるかどうかは関係がなくなりました。列挙タイプ access::placeholder も非推奨になりました。テンプレート・パラ
メーターにかかわりなく、適切なコンストラクターを呼び出すことで、プレースホルダー・アクセサーを構築できるようになりました。

• accessor::is_placeholder() の戻りタイプは constexpr ではなくなりました。

428 | 付録 D 前バージョンからの変更点

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点• メンバー関数 handler::require() は、プレースホルダーであるかどうかに関係なく、target::device、target::constant_buffer ま
たは target::host_task をターゲットとする任意の accessor を呼び出すことが可能になりました。

• タイプ・タグ・パラメーターを受け取る新しい accessor コンストラクターが追加されました。これにより、クラス・テンプレート・パ
ラメーターを C++ クラス・テンプレート引数のデダクション (CTAD) を介して推測できるようになりました。

• buffer メ ン バ ー 関 数 get_access() に target テ ン プ レ ー ト ・ パ ラ メ ー タ ー の デ フ ォ ル ト 値 が 追 加 さ れ た た め 、access_mode::read_write アクセサーを取得するテンプレート・パラメーターを指定する必要がなくなりました。

• accessor テンプレート・パラメーター Dimensions と AccessMode にデフォルト値が設定されたため、必要なテンプレート・パ
ラ メ ー タ ー は DataT の み に な り ま し た 。 さ ら に 、 デ フ ォ ル ト の ア ク セ ス モ ー ド は 、 DataT タ イ プ の 定 数 に 応 じ て 、access_mode::read_write または access_mode::read のどちらかになります。これにより、const 修飾タイプを使用するだけで、
read-only アクセサーを宣言できます。

• read-only accessor の 2 つの形式間に暗黙の変換が追加されました (1 つの形式は const DataT と access_mode::read を持ち、もう 1 つは非 const の DataT と access_mode::read を持ちます)。read-write accessor から、read-only 形式への暗黙の変換もあります。accessor の value_type および reference メンバータイプは、読み取り専用アクセサーの const に変更されました。

• 要素への参照を 返す accessor のメンバー関数は、 read-only アクセサ ーの const 参照を返すように変更されまし た。
get_pointer() メンバー関数も変更され、read-only アクセサーの const ポインターを返すようになりました。

• accessor メンバー関数 get_pointer() は生のポインターを返すようになりました。multi_ptr クラスを適切な空間に返す
get_multi_ptr() メンバー関数が導入されました。

• accessor クラスは ReversibleContainer の C++ 要件を満たすようになりました。これには、begin および end イテレーターを返すこと、カーネルに渡しても逆参照されないデフォルトの構成可能なアクセサーを指定すること、およびそれらを同等に比較できること、などが含まれますが、これらに限定されるわけではありません。

• ほとんどの accessor メンバー関数は noexcept としてマークされます。
• レンジ付きアクセサーは、レンジ外の要素を読み取りできなくなりました。アクセスすると動作は未定義となります。
• オフセットを持つレンジ付きアクセサーのインデックス・オペレーターのセマンティクスが変更されました。operator[](0) を呼び出すと、ベースとなるバッファーの最初の要素への参照ではなく、レンジの最初の要素への参照が返されるようになりました。

• レンジがゼロのバッファーとアクセサーの動作が明確になりました。
SYCL 2020 では、SYCL デバイスのメモリーモデルから定数メモリーがなくなりました。
カーネルを修飾する C++ 属性がより適切に記述でき、それらの位置が変更されカーネル関数に直接適用されるようになりました (以前は、カーネルが呼び出すデバイス関数に適用されたため、実装は情報を包括するカーネルに伝搬する必要がありました)。古い C++
属性形式は SYCL 仕様に含まれなくなりました。
表 178 のビルトイン整数数学関数のリストに ctz() が追加されました。clz() に引数が 0 の場合が追加されました。
ク ラ ス vector_class 、 string_class 、 function_class 、 mutex_class 、 shared_ptr_class 、 weak_ptr_class 、 hash_class お よ び
exception_ptr_class が API か ら 削除さ れ 、標 準 クラス std::vector 、 std::string、std::function 、 std::mutex 、std::shared_ptr 、
std::weak_ptr、std::hash そして std::exception_ptr に置き換えられました。
std::unique_ptr を受け取る特定の sycl::buffer API が削除されました。動作は SYCL 1.2.1 と同じですが API が簡略化されています。
std::shared_ptr を受け取る API はまだ存在し、std::unique_ptr prvalue から std::shared_ptr への暗黙の変換が行われることから、以前と同じように std::unique_ptr を使用してメモリーの所有権を譲渡できます。
parallel_for、nd_range、nd_item および itemクラスへのオフセットは非推奨になりました。そのため、並列反復空間はすべて(0,0,0) で 始 ま る た め 、 開 発 者 は オ フ セ ッ ト 計 算 を 自 身 で 行 う 必 要 が あ り ま す 。 nd_item.get_global_linear_id() と
nd_item.get_local_linear_id() の動作が明確になりました。

付録 D 前バージョンからの変更点 | 429

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点
4.8 節の統合共有メモリー (USM) が、ポインターベースのデータ管理を可能にするため追加されました。これは、ホストとデバイス間のさまざまなアクセス規則によっていくつかの割り当て方法を定義します。USM の目的はバッファーを補完することであり、バッファーを置き換えるものではありません。
queue クラスは、送信された操作が順番に実行されるキューの順序付けセマンティクスを必要とする新しい property を受け取ります。
queue クラスは、submit メンバー関数のコマンド・グループ・ハンドラーではなく、キュー・オブジェクトで直接カーネルを呼び出す新しいメンバー関数を受け取ります。
context と device パラメーターの両方を受け入れる queue コンストラクターのオーバーロードが拡張され、デバイスをコンテキスト
内のデバイスまたはコンテキスト内のデバイスの下位デバイスのいずれかにできるようになりました。
program クラスは削除され、新しいクラス kernel_bundle に置き換えられました。これにより、タイプセーフでスレッドセーフな機能が提供されます。kernel クラスが変更され、一部のメンバー関数が削除されました。
特殊化定数のサポートが追加されました。これにより、SYCL カーネル関数は、カーネルが呼び出されるまで値が変化しない定数変数を利用できます。SYCL カーネル関数は、カーネルが特殊化定数の値を読み取る kernel_handler タイプのオプション・パラメーターが利用できるようになりました。
SYCL context と queue のコンストラクターは、explicit タイプへの変換に起因するコンストラクターのあいまいさを解決するため明示的に作成されます。
ホストとデバイス間で共有されるデータの C++ 標準レイアウトの要件が緩和されました。SYCL では、3.13.1 節で定義されるように、ホストとデバイス間でデータがデバイスコピー可能である必要があります。
work-item のグループの概念は、work-group と sub-group を含むように一般化されました。work-group は SYCL 1.2.1 と同様に
sycl::group クラスで表現され、sub-group は新しい sycl::sub_group クラスで表現されます。
queue の host_task メンバー関数は、SYCL メモリーモデルに準拠し、キューにホストタスクをエンキューしてネイティブ C++ 関数を呼び出す SYCL ランタイムをスケジュールできるように導入されました。また、ホストタスクは、オプションの interop_handle クラスを使用して、DAG のポイントで関連付けられているネイティブ SYCL バックエンド・オブジェクトとの相互運用をサポートします。
4.17.4 節に C++17 アルゴリズム・ライブラリー・ベースのアルゴリズムのライブラリーが追加されました。これらのアルゴリズムは、開発者がグループの work-item を使用して、一般的な並列アルゴリズムを導入する簡単な方法を提供します。
sycl::group クラスの定義は、4.17.3 節の新しいグループ関数をサポートするように変更されました。汎用プログラミングを可能にするため、新しいメンバータイプと変数が追加され、sycl::group クラスの work group に関連付けられたすべての機能をカプセル化できるようにメンバー関数が変更されました。詳細については表 121 をご覧ください。
nd_item クラスの barrier と mem_fence メンバー関数は削除されました。barrier メンバー関数は、work-group または sub-groupのいずれかを同期するために使用される group_barrier() 関数に置き換えられました。mem_fence メンバー関数は、atomic_fence
関数に置き換えられました。この関数は、std::atomic_thread_fence と連携してメモリーの順序とスコープを制御します。
SYCL vec クラスの変更を 4.14.2 節に示します。

• operator[] が追加されました。
• 単項 operator+() および operator-() が追加されました。
デバイスの選択は、4.6.1.1 節で説明されるデバイスセレクターとして使用されるランク関数に基づいて、簡単な API を使用できるようになりました。

430 | 付録 D 前バージョンからの変更点

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点
新しいデバイス・セレクター・ユーティリティー aspect_selector が 4.6.1.1 節に追加されました。これは、要求されたすべてのアスペクトを持つデバイスのみを選択するセレクター・オブジェクトを返します。
デバイスクエリー info::fp_config::correctly_rounded_divide_sqrt は非推奨となりました。
SYCL カーネルのリダクション・セマンティクスにより変数式を簡単にするため、reduction 関数と reducer クラスで構成される新しい
リダクション・ライブラリーが導入されました。4.9.2 節を参照してください。
SYCL 1.2.1 の atomic クラスは非推奨となり、新しい atomic_ref インターフェイスが採用されました。
SYCL 例外クラスの階層は、単一の例外タイプに集約されています。例外は std::exception から派生するようになりました。さまざまなエラーがエラーコードを介して判別できるようになりました。これは、C++ のエラー・コード・メカニズムと連携しています。
新しいエラー・コード・メカニズムは、以前の get_cl_code インターフェイスも一般化し、バックエンド固有のエラーコードを照会する汎用インターフェイスを提供します。
デフォルトの非同期ハンドラーの動作が定義されたため、ユーザー定義の非同期ハンドラー関数が定義されていなくても、非同期エ
ラーが発生するプログラムを異常終了できます。これにより、アプリケーション開発の初期段階で非同期エラーが見過ごされるのを防ぎます。
parallel_for などのカーネル呼び出し関数は、const 参照によってカーネル関数を受け取れるようになりました。カーネル関数には、
const 修飾された operator() が必要であり、実装によってゼロまたは複数回コピーできるようになりました。これらを明確にすること
で、特定のデバイスに対して実装に柔軟性を持たせることができ、ユーザーがカーネル・ファンクターに期待すべき動作を定義できます。
カーネル・ファンクターを mutable としてマークすることはできません。また、カーネル・ファンクターに格納された状態を介して workitem 間のデータを共有してはなりません。
デバイスアスペクトと呼ばれる新しい概念が追加されました。これは、デバイスがサポートするオプション機能のセットを表します。この新しいメカニズムは、has_extension() 関数と get_info() の使い方の代替となります。
新しい 6 章では、ベンダーと Khronos Group が SYCL 言語の拡張機能を追加する方法を説明しています。
ライブラリーとのインターフェイスを簡素化するため、device と context の両方を取得する queue コンストラクターが追加されました。
parallel_for インターフェイスは、range に変わって中括弧で囲んだ初期化子リストを受け入れ、常に item 引数を受け入れるように簡略化されています。カーネル呼び出し関数も汎用ラムダ式を受け入れるように変更されました。1 次元 item および 1 次元 id からスカラータイプへの暗黙的な変換が定義されました。これらの変更はすべて、通常の使い方で簡潔な SYCL コードの記述を可能にします。
ゼロ範囲のインデックス空間や nd_range でカーネルを実行する動作が明確に定義されました。
一部のデバイス固有のクエリーは、“work-group” (get_workgroup_info) および sub-group (get_sub_group_info) クエリーに代わり、より明確な「デバイス固有のカーネル」の get_info クエリー (info::kernel_device_specific) に変更されました。
sycl::vec を解釈および実装する際の曖昧性を解決するため、新しい数学配列タイプ marray が定義されました。
以下は、SYCL アドレス空間の変更です。

• アドレス空間の解釈が大幅に改善されました。
• 汎用アドレス空間が導入されました。
• 定数アドレス空間が非推奨になりました。

付録 D 前バージョンからの変更点 | 431

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点• 注釈のないポインター/参照 (生のポインター/参照) の動作は、コンパイルモードに依存します。コンパイラーは、注釈のないポイ
ンター/参照が汎用アドレス空間をアドレス指定していると解釈するか、推測できます。

• アドレス空間の推定における曖昧性が明確になりました。デダクション・タイプはユーザー定義のタイプには影響しません。
以下は、multi_ptr インターフェイスの変更です。

• 汎用アドレス空間を表現するため、access::address_space::generic_space が追加されました;• access::address_space::constant_space は非推奨となりました。
• multi_ptr インターフェイスの意味合いを選択できるようにテンプレート・パラメーターが追加されました。現在異なる 3 つのイン
ターフェイスがあります。

◦ 修飾されていないタイプを公開するインターフェイス。返されるポインターと参照は、アドレス空間が注釈付けされません。
◦ 修飾されたタイプを公開するインターフェイス。返されるポインターと参照は、アドレス空間が注釈付けされます。
◦ レガシー 1.2.1 インターフェイス (非推奨)。
• 1.2.1 のインターフェイスは非推奨です。
• constant_ptr は非推奨です。
• global_ptr、local_ptr および private_ptr エイリアスは、新しいパラメーターを受け入れます。
• 修飾されていないポインターを multi_pointer にキャストするため address_space_cast フリー関数が追加されました。
• 汎用アドレス空間の構築/変換オペレーターが追加されました。
• 注釈のないポインターを受け取るコンストラクターと代入オペレーターが削除されました。
• ポインターへの暗黙の変換は非推奨になりました。代わりに get を使用します。
• メンバー関数 get の戻りタイプは、選択されたインターフェイスによって異なります。
• ベースとなるポインターを注釈なしのポインターとして返すメンバー関数 get_raw が追加されました。
• ベースとなるポインターを注釈付きのポインターとして返すメンバー関数 get_decorated が追加されました。
• ランダムアクセスを提供するインデックス演算子が追加されました。
cl::sycl::byte は非推奨となり、代わりに C++17 std::byte を使用します。
ホストデバイスを提供する SYCL 実装は不要になりました。代わりに、実装は少なくとも 1 つのデバイスを提供することが要求されます。実装では、ホストに実装されるデバイスの提供は引き続き許可されますが、必須ではなくなりました。この仕様では、「ホストデバイス」の特別なセマンティクスは定義されなくなったため、ホストデバイス固有の API が削除されました。
device と platform クラスのデフォルト・コンストラクターが変更され、デフォルトデバイスのコピーと、デフォルトデバイスを含むプ
ラットフォームのコピーが作成されます。以前は、ホストデバイスのコピーとホストデバイスを含むプラットフォームのコピーが返されていました。event クラスのデフォルト・コンストラクターも変更され、デフォルトで構築された queue からのイベントが作成されます。
以前は、ホストのバックエンドを使用するイベントが作成されていました。
ハンドラークラスの明示的なコピー関数が、ハンドラークラスのショートカットとしてキュークラスに導入されました。これにより、
ショートカット関数が暗黙的にコマンドグループを作成し、handler::require を呼び出すため、特定のケースでコードの冗長性を減らすことができます。これは、改良されたプレースホルダー・アクセサーによって可能になりました。
情報クエリー記述子は、それに応じて命名される名前空間下の構造に変更されました。param_traits が削除され、情報クエリーの戻りタイプが記述子に含まれるようになりました。sycl::info::device::max_work_item_sizes は、work-item の最大サイズの次元数に対応する次元パラメーターを受け取るテンプレートになりました。

432 | 付録 D 前バージョンからの変更点

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点
以下にサイズ情報の取得に関連する変更を示します。

• すべての get_size() メンバー関数は非推奨となり、noexcept としてマークされた byte_size() に置き換えられました。
• すべての get_count() メンバー関数は非推奨となり、noexcept としてマークされた size() に置き換えられました。
• vec クラスでは、関数 byte_size() と size() は静的メンバー関数となりました。
• stream クラスでは、get_size() が非推奨となり size() に置き換えられましたが、stream::byte_size() は使用できません。
• サンプルイメージおよび非サンプルイメージのアクセサーは、byte_size() ではなく size() のみを定義します。
デバイス記述子 info::device::max_constant_buffer_size と info::device::max_constant_args は、SYCL 2020 では非推奨です。
buffer_allocator は、データタイプでテンプレート化され、C++ の名前付き要件 Allocator に従います。
SYCL id と range には、SYCL 1.2.1 で漏れていた単項 + と - 操作、プリフィクス ++ と -- 操作、ポストフィクス ++ と -- 操作が含まれるようになりました。
SYCL 1.2.1 では、2 つの accessor パラメーターを持つ handler::copy() オーバーロードで、コピーされるメモリー容量を決定するアク
セサーのサイズが明確に指定されていませんでした。この仕様では、src アクセサーのサイズが使用されることが明確にされています。

付録 D 前バージョンからの変更点 | 433

SYCL 2020 リビジョン 6 - D.1 SYCL 1.2.1 から SYCL 2020 への変更点

付録 E 参考資料
International Organization for Standardization (ISO). “Programming Languages — C++”.ISO/IEC 14882:2017, 2017.
International Organization for Standardization (ISO). Accepted resolution to C++ Standard Core Language Defect Report
DR2325. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0593r6.html (英語).
Khronos OpenCL Working Group. The OpenCL Extension Specification, Version 1.2.25 (2/13/18).
http://www.khronos.org/registry/cl/specs/opencl-1.2-extensions.pdf (英語).
Khronos OpenCL Working Group. The OpenCL Specification, Version 1.2.19 (11/14/12).
https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf (英語) .
Khronos OpenCL Working Group. The OpenCL Specification, Version 2.0.29 (July 21, 2015).
https://www.khronos.org/registry/OpenCL/specs/opencl-2.0.pdf (英語) .
International Organization for Standardization (ISO). “Programming Languages — C++, Langages deprogrammation — C++“,International Standard ISO/IEC 14882:2020(E), Sixth edition 2020-12, 2020.

付録 E 参考資料 | 434

SYCL 2020 リビジョン 6 - 用語集

用語集
アクセサー (accessor)
アクセサーは、コマンドがバッファーまたはイメージクラスによって管理されるデータにアクセスできるようにするクラス、またはSYCL カーネル関数がデバイスのローカルメモリーにアクセスできるようにするクラスです。アクセサーはコマンドグループ間の依存関係を表現するためにも利用されます。詳細については、4.7.6 節をご覧ください。

アプリケーション・スコープ (application scope)
アプリケーションのスコープは、最初に SYCL ランタイム・クラス・オブジェクトの構築から始まり、最後にオブジェクトの破棄で終わります。アプリケーションは、SYCL ランタイムではなく C++ SYCL アプリケーションを参照します。

アスペクト (aspects)
オプションの機能をサポートするか決定するデバイスの特性。アスペクトは常にブール値であるため、デバイスにアスペクトがあるか、ないかのいずれかです。

非同期エラー (asynchronous error)
SYCL 非同期エラーは、エラーの原因となるアクションを呼び出すホスト API 呼び出し後に発生するエラーであり、ホスト API 呼び出しから C++ 例外としてエラーをスローすることはできません。このようなエラーは、SYCL タスクグラフの依存関係が満たされた場合に実行されるデバイスカーネル呼び出しから生成されます。これは、ホストコードの実行とは非同期に発生します。完全な説明と関連する
非同期エラー処理のメカニズムについては、4.13 節を参照してください。

非同期ハンドラー (async_handler)
非同期エラー・ハンドラー・オブジェクトは、コンテキストや関連イベント内でキューのコマンドグループの実行からトリガーされたすべての非同期エラーを処理するコードを提供する関数クラスのインスタンスです。完全な説明については、4.13.2 節を参照してください。

バリア (barrier)
バリアは、コマンドキューの同期ポイントもしくはカーネル実行の work-item のグループであるかに応じて、コマンド・キュー・バリアまたはカーネル実行グループバリアのどちらかになります。

ブロッキング・アクセサー (blocking accessor)
ブロッキング・アクセサーは即時アクセスを提供し、破棄されるまでアクセスの提供を継続するアクセサーです。完全な説明については、
4.7.6 節を参照してください。

バッファー (buffer)
バッファークラスは、SYCL C++ ホスト・アプリケーションと SYCL デバイスカーネルのデータを管理します。バッファークラスは、コンストラクターの種類に応じて、コンストラクターに渡されるホストポインターを取得する場合があります。
バッファークラスには、アクセサークラスとメモリー転送をトレースし、異なるカーネル間のデータの一貫性を保持する役割があります。
SYCL ランタイムは、バッファー・オブジェクトの存続期間中にホストとデバイス両方のメモリー割り当てを管理します。完全な説明については、4.7.2 節を参照してください。

用語集 | 435

SYCL 2020 リビジョン 6 - 用語集

バンドル状態 (bundle state)
SYCL バンドルの状態はカーネルバンドルの状態を示し、SYCL プログラミング API でその機能を確認できます。状態には、入力、オブジェクトまたは実行可能があります。

コマンド (command)
SYCL カーネル関数の呼び出し、ホストタスクの呼び出し、または非同期コピーなど、キューに送信されたワークの実行を要求します。

コマンドグループ (command group)
SYCL では、デバイス上のデータを処理する操作は、コマンドグループ関数オブジェクトを使用して表現されます。各コマンドグループ
関数オブジェクトには、カーネルを使用してデバイス上でデータを正しく処理するのに必要なすべてのワークを実行するコマンド・グ
ループ・ハンドラーがあります。この方法では、データを転送および処理するコマンドグループは、実行するデバイス上のコマンドグ
ループとしてエンキューされます。コマンドグループは、自動的に SYCL キューに送信されます。

コマンドグループ関数オブジェクト (command group function object)
コマンド・グループ・ハンドラーへの参照を受け取り、キューによって送信できるコマンドグループを定義する operator() で呼び出し可
能なタイプ。関数オブジェクトは、名前付きタイプ、ラムダ関数、または std::function にすることができます。

コマンド・グループ・ハンドラー (command group handler)
コマンド・グループ・ハンドラー・クラスは、コマンド・グループ・スコープ内で実行できるコマンドのインターフェイスを提供します。これは、コマンド・グループ・スコープ内のすべてのデータアクセス要求に対しスコープ・オブジェクトとして提供されます。完全な説明については、4.9.4 節を参照してください。

コマンド・グループ・スコープ (command group scope)
コマンド・グループ・スコープは、コマンドグループ関数オブジェクトで定義される関数です。コマンドグループのコマンド・グループ・ハ
ンドラー・オブジェクトの有効範囲は、コマンドグループのスコープに制限されます。詳細については 4.9.3 節をご覧ください。

コマンド・キュー・バリア (command queue barrier)
SYCL API は、SYCL コマンドキューで同期を強制する 2 つの関数バリアントを提供します。sycl::queue::wait_and_throw() と
sycl::queue::wait() 関数は、SYCL コマンドキューがコマンドグループ関数オブジェクトの実行を待機した後、実行を継続できるようにします。

定数メモリー (constant memory)
カーネルの実行中、定数が保持されるメモリー領域。SYCL ランタイムは、定数メモリーに配置されたメモリー・オブジェクトを割り当てて初期化します。

コンテキスト (context)
コンテキストは、SYCL バックエンド API がプラットフォームに関連付けられたデバイスグループと対話するのに必要なランタイムデー
タ構造と状態を表します。コンテキストは sycl::context クラスとして定義されます。詳細は 4.6.3 節を参照してください。

436 | 用語集

SYCL 2020 リビジョン 6 - 用語集

制御フロー (control flow)group 内のすべての work-item が同じステートメントを実行する場合、それらは収束した制御フローで実行されると表現します。制御
フローが分岐するのは、グループ内の異なる work-item が異なる文のシーケンスを実行する場合です。これは、通常、異なる条件を評価した結果です (選択文やループなど)。

コア SYCL 仕様 (core SYCL specification)
SYCL 言語仕様 (このドキュメント) の説明であり、バックエンド仕様の説明と拡張機能の説明を除きます。

下位デバイス (descendent device)
デバイス D の下位デバイスには、D のすべてのサブデバイス、そしてそれらのデバイスのサブデバイスなどが含まれます。

デバイス (device)
SYCL デバイスは、SYCL カーネルを実行するハードウェアを抽象化したものです。

デバイス・コンパイラー (device compiler)
SYCL デバイス・コンパイラーは、有効な SYCL アプリケーションからデバイスバイナリーを生成するコンパイラーです。完全な説明については第 5 章を参照してください。

コピー可能なデバイス (device copyable)
ホストとデバイス間で共有されるデータは、通常、デバイスコピー可能なタイプとして 3.13.1 節の制限に従うタイプでなければなりません。

デバイス関数 (device function)
デバイス関数とは、デバイス上で実行できる SYCL アプリケーションの任意の関数のことです。これには、SYCL カーネル関数とカーネルが呼び出す関数が含まれます。

デバイスイメージ (device image)
デバイスイメージは、1 つまたは複数のカーネルを、実装定義された形式で表現したものです。デバイスイメージは、カーネルを中間言語表現にコンパイルしたもので、実行時にデバイスで呼び出し可能な形式に変換する必要があるもの、またはネイティブコード形式のコンパイル済みカーネルで翻訳することなく呼び出し可能であるもの、あるいはソースコード表現で呼び出す前にコンパイルが必要なものなどがあります。その他の表現も可能です。

デバイスイメージ選択関数 (device image selection function)
デバイスイメージのシーケンスを指すカーネルバンドルの begin と end イテレーターを受け取り、選択されたデバイスイメージへのイ
テレーターを返す呼び出し可能なオブジェクトです。

デバイスセレクター (device selector)
さまざまな場所で使用されるデバイスの選択を可能にします。これは、デバイス参照を受け取り、整数ランクを返す呼び出し可能なオブジェクトです。最も大きな非負値のデバイスが選択されます。詳細は 4.6.1.1 節を参照してください。

用語集 | 437

SYCL 2020 リビジョン 6 - 用語集

イベント (event)SYCL ランタイムで実行される操作の状態を示すオブジェクト。

実行形式 (executable)
SYCL カーネル関数を実行可能ファイルとして表す、カーネルバンドルの状態。

汎用メモリー (generic memory)
汎用メモリーは、グローバルメモリー、ローカルメモリーおよびプライベート・メモリー領域を表す仮想メモリー領域です。

グローバル id (global id)
OpenCL と同様に、グローバル ID は work-item を一意に識別する際に使用され、カーネルの実行時に指定されたグローバル workitem 数から導かれます。グローバル ID は、次元ごとに 0 から始まる 1 次元、2 次元、または 3 次元の値です。

グローバルメモリー (global memory)
グローバルメモリーは、デバイスで実行されるすべての work-item にアクセスできるメモリー領域です。

グループ (group)work-group や sub-group など、SYCL カーネルを実行するインデックス空間内の work-item のグループ。

グループバリア (group barrier)work-item のグループ内の同期関数。グループ内のすべての work-item は、バリアを超えて実行を継続する前に、バリアを実行する必要があります。さらに、グループ内のすべての work-item は、バリアで同期する前に mem-fence を解放し、グループ内のすべてのwork- item はバリアで同期した後に mem-fence を取得します。バリアを実装する内部のアトミック・オブジェクトに対するアトミック
操作を介してフェンスを解放します。

項目 (h-item)SYCL カーネルの階層を実行するインデックス空間内の単一の work-item を表す一意の識別子。1、2、もしくは 3 次元にすることができます。SYCL インターフェイスでは、h-item は、h_item クラスによって表されます (4.9.1.6 節を参照)。

ホスト (host)
ホストは、SYCL API を含む C++ アプリケーションを実行するシステムです。

ホストポインター (host pointer)
ホスト上のメモリーへのポインター。デバイスから直接アクセスすることはできません。

ホストタスク (host task)
SYCL の依存関係規則に準拠してスケジュールされた、ネイティブ C++ 呼び出し可能オブジェクトを呼び出すコマンド。

ホスト・タスク・コマンド (host task command)
ネイティブ C++ 関数をスケジュールする際にコマンドグループ内で使用できるコマンドタイプ。

438 | 用語集

SYCL 2020 リビジョン 6 - 用語集

id
インデックス空間内の item の一意な識別子。SYCL カーネルの実行モデルは、nd-range であるため、1、2、もしくは 3 次元のインデックス空間にすることができます。インデックス空間クラスの 1 つです。完全な説明については、4.9.1.3 節を参照してください。

イメージ (image)SYCL イメージは、バッファーと同様に、多次元構造化配列の抽象化です。イメージは unsampled_image と sampled_image を参照
できます。完全な説明については、4.7.3 節を参照してください。

実装定義 (implementation-defined)
SYCL に準拠した実装間で異なることが許可されている動作。SYCL 実装者は、実装定義の動作を文書化しなければなりません。

インデックス空間クラス (index space classes)
OpenCL と同様に、カーネル実行モデルは nd-range インデックス空間を定義します。nd-range を定義する SYCL ランタイムクラスは
sycl::nd_range であり、sycl::range クラスを使用して表現されるグローバルおよびローカル work- item のサイズを入力として受け取ります。定義される nd-range でインデックスを作成するカーネル・ライブラリー・クラスは以下です。

• sycl::id: id を表す基本インデックス・クラス。
• sycl::item: グローバル id と ローカル id を含む item インデックス・クラス。
• sycl::nd_item: グローバル id、ローカル id および work-group id を含む nd-item インデックス・クラス。
• sycl::group: work-group id と work-group のメンバー関数を含むグループクラス。
入力 (input)
ソースまたは中間表現として SYCL カーネル関数を表す、カーネルバンドルの状態。

項目 (item)
item id は、グローバル id、work-group id および ローカル id を取得するインターフェイスです。詳細は 4.9.1.4 節を参照してください。

カーネル (kernel)
カーネルは、デバイス向けにコンパイルされた SYCL カーネル関数であり、呼び出すデバイス関数のすべてが含まれます。カーネルは、
SYCL カーネル関数がカーネル起動コマンドでデバイスに送信されると、暗黙的に生成されます。ただし、カーネルバンドルを事前コンパイルすることで、手動でカーネルを作成することもできます (4.11 節を参照)。

カーネルバンドル (kernel bundle)
カーネルバンドルは、同じコンテキストとデバイスのセットに関連付けられたデバイスイメージのコレクションです。カーネルバンドルには、入力、オブジェクトまたは実行可能の 3 つの状態があります。実行可能な状態のカーネルバンドルは、デバイス上ですぐに呼び出すことができますが、ほかの状態のバンドルは、呼び出す前に実行可能な状態に変換する必要があります。

カーネルハンドラー (kernel handler)
カーネルスコープで使用できる SYCL カーネル関数が呼び出される状態を表現します。

用語集 | 439

SYCL 2020 リビジョン 6 - 用語集

カーネル起動コマンド (kernel invocation command)
SYCL カーネル関数をスケジュールするためコマンドグループで使用できるコマンドのタイプには、single_task、parallel_for および
parallel_for_workgroup のすべてのバリアントが含まれます。

カーネル名 (kernel name)
カーネル名は、カーネル関数への名前割り当てに使用されるクラスタイプであり、ホストシステムとデバイス・コンパイラーが出力する
カーネル・オブジェクトをリンクする際に利用されます。カーネル命名の詳細は 5.2 節をご覧ください。

カーネルスコープ (kernel scope)
SYCL カーネル関数の operator() の関数スコープ。カーネルから呼び出される関数やメンバー関数もカーネルスコープでコンパイルされることに注意してください。カーネルスコープは、C++ 言語の拡張機能やデバイスの機能を反映する制限を可能にします。機能拡張や制限事項は、SYCL デバイスのコンパイラー仕様で定義されます。

ローカル id (local id)
work-group のほかの work-item 間の work-item の一意な識別子。

ローカルメモリー (local memory)
ローカルメモリーは、work-group に関連付けられたメモリー領域であり、その work-group 内の work-item のみがアクセスできます。

ネイティブ・バックエンド・オブジェクト (native backend object)
特定のバックエンドで定義された不透過なオブジェクトであり、そのバックエンドの高レベル SYCL オブジェクトを表現します。すべての SYCL タイプにネイティブ・バックエンド・オブジェクトがある保証はありません。

ネイティブ特殊化定数 (native-specialization constant)
コンパイル時にオンライン・コンパイラーが即値として利用できる値を持つデバイスイメージの特殊化定数。

nd-item
SYCL カーネルを実行するインデックス空間内の単一 work-item と work-group を表現する一意の識別子。1、2、もしくは 3 次元にすることができます。SYCL インターフェイスでは、nd-item は nd_item クラスで表現されます (4.9.1.5 節を参照)。

nd-range
SYCL カーネルを実行するインデックス空間、work-group 内の work-item の分散を表現します。グローバル work-item 数を指定す
る range、ローカル work-item 数を指定する range、およびグローバルオフセットを指定する id が含まれます。次元は 1、2、もしくは3 にできます。nd-range 内の各 range の最小サイズは次元ごとに 0 です。いずれかの次元がゼロに設定さてれいる場合、すべての次
元のインデックス空間はゼロになります。SYCL インターフェイスでは、nd-range は nd_range クラスで表現されます (4.9.1.2 節を参照)。

メモリーフェンス (mem-fence)
メモリーフェンスは、2 つのフェンスを互いに同期するアトミック操作 (または、フェンスがグループバリアの一部である場合、アトミック
操作がフェンスを同期するように暗黙的に同期する) と組み合わせることで、メモリーのロードとストア操作のリオーダーを制限します。
sycl::atomic_fence 関数は、memory_scope 引数で指定されたすべての work-item とデバイスに対するフェンスとして機能します。

440 | 用語集

SYCL 2020 リビジョン 6 - 用語集

オブジェクト (object)
SYCL カーネル関数を実行不可なオブジェクトとして表す、カーネルバンドルの状態。

プラットフォーム (platform)
単一のバックエンドで管理されるデバイスのコレクションです。

プライベート・メモリー (private memory)work-item 専用のメモリー領域。1 つの work-item のプライベート・メモリーで定義された変数は、別の work-item からは見えません。
sycl::private_memory クラスはリスト 1 に示すように、階層的な API の work-item のプライベート・メモリーへのアクセスを可能にします。

キュー (queue)
SYCL コマンドキューは、SYCL デバイスで実行されるコマンドグループを保持するオブジェクトです。SYCL は、デバイスキューを使用
して異種プラットフォームの統合を可能にします。これは、SYCL アプリケーションを SYCL デバイスで実行するための最小要件です。
完全な説明については、4.6.5 節を参照してください。

レンジ (range)
SYCL カーネルを実行するインデックス空間内の work-item または work-group 数を表現します。1、2、もしくは 3 次元にすることができます。SYCL インターフェイスでは、work-group は group クラスで表現されます (4.9.1.7 節を参照)。

レンジ付きアクセサー (ranged accessor)
レンジ付きアクセサーは、データバッファーへのゼロ以外のオフセット、またはデータバッファーのレンジよりも小さなアクセスレンジ、
またはその両方で構築されたホストまたはバッファーアクセサーです。詳細は 4.7.6.8 節を参照してください。

リダクション (reduction)
二項オペレーターを使用して、複数の値を組み合わせて不特定の順番で単一の値を生成する操作。オペレーターが非結合または非可換である場合、リダクションの動作は非決定的である可能性があります。

ルートデバイス (root device)
sub-device ではないデバイスです。device::get_devices() 関数は、すべてのルートデバイスのベクトルを返します。

5 の法則 (rule of five)
特定のクラスに対し、コピー・コンストラクター、ムーブ・コンストラクター、コピー代入オペレーター、ムーブ代入オペレーター、およびデストラクターの少なくとも 1 つが明示的に宣言される場合、それ以外のすべても明示的に宣言しなければなりません。

ゼロ規則 (rule of zero)
特定のクラスに対し、コピー・コンストラクター、ムーブ・コンストラクター、コピー代入オペレーター、ムーブ代入オペレーター、およびデストラクターがすべてインライン展開され、パブリックでデフォルト化される場合、それらはいずれも明示的に宣言する必要がありません。

用語集 | 441

SYCL 2020 リビジョン 6 - 用語集

SMCP
単一ソース複数コンパイルパス (SMCP) を使用すると、単一のソースファイルを複数のコンパイラーで解析して、コンパイルターゲット
ごとにネイティブプログラムを作成できます。例えば、ホストをターゲットにする標準の C++ CPU コンパイラーは、SYCL ファイルを解
析して計算の一部分をほかのデバイスにオフロードする C++ SYCL アプリケーションを作成します。SYCL デバイス・コンパイラーは、同じソースファイルを解析して SYCL カーネルのみをコンパイルの対象にします。

特殊化定数 (specialization constant)
SYCL カーネル関数のコンパイル時まで値が不明である定数変数。

特殊化 id (specialization id)
カーネルバンドルのコンパイル前に値を設定する SYCL アプリケーションと、呼び出し中に値を取得する SYCL カーネル関数の両方
で、特殊化定数への参照を示す識別子です。

文字列カーネル名 (string kernel name)
文字列形式の SYCL カーネル関数の名前であり、相互運用により作成されるカーネル関数名、またはタイプカーネル名の文字列形式にすることができます。

サブグループ (sub-group)
SYCL sub-group (sycl::sub_group クラス) は、同時に実行される work-group 内の関連する work-item のコレクションを表し、同じ
work-group のほかの sub-group に対し独立して進行する可能性があります。sycl::sub_group クラスの詳細については、4.9.1.8 節を参照してください。

サブグループ・バリア (sub-group barrier)
sub-group 内のすべての work-item の グループバリアです。

サブグループ・メモリー・フェンス (sub-group mem-fence)
sub-group 内のすべて work-item のメモリーフェンスです。

SYCL アプリケーション (SYCL application)
SYCL アプリケーションは、デバイス上でカーネルを実行するため SYCL プログラミング・インターフェイスを使用する C++ アプリケー
ションです。

SYCL バックエンド (SYCL backend)
異種プログラミング API を使用する SYCL プログラミング・モデルの実装。SYCL バックエンドは、1 つまたは複数の SYCL プラット
フォームを提供します。例えば、OpenCL バックエンドは ICD ローダーを介して、複数の OpenCL プラットフォームを提供できます。

SYCL バックエンド API (SYCL backend API)
特定の SYCL バックエンドに対して SYCL コードを記述するための API。

SYCL C++ テンプレート・ライブラリー (SYCL C++ template library)
テンプレート・ライブラリーは、SYCL 開発者にプログラミング・インターフェイスを提供する C++ テンプレート・クラスのセットです。

442 | 用語集

SYCL 2020 リビジョン 6 - 用語集

SYCL ファイル (SYCL file)
SYCL API 呼び出しを含む SYCL C++ ソースファイル。

SYCL カーネル関数 (SYCL kernel function)
コマンド・グループ・ハンドラーのカーネルを投入するメンバー関数に渡すことができる、id、item、nd-item または work-group を受け取る operator() で呼び出し可能なタイプ。SYCL カーネル関数は、カーネルのエントリーポイントを定義します。関数オブジェクトは、名前付きコピー可能デバイスタイプやラムダ関数とすることができます。

SYCL ランタイム (SYCL runtime)
SYCL ランタイムは SYCL API 仕様の実装です。SYCL ランタイムは、各種プラットフォーム、デバイス、コンテキストおよび、ホストとSYCL バックエンド・コンテキスト間のデータのメモリー処理を管理することで、SYCL プログラムのセマンティクスを正しく実行することを可能にします。

カーネル名タイプ (type kernel name)
タイプ形式の SYCL カーネル関数の名前です。これは、カーネル起動コマンドで指定されるカーネル名、またはSYCL カーネル関数として使用される関数オブジェクト・タイプのいずれかです。

USM
統合共有メモリー (USM) は、バッファー・プログラミング・モデルによるポインターベースの代替手段を提供します。USM は以下を可能にします。

• 割り当てアクセスをバッファーの代わりにポインターとすることにより、既存のコードベースへの統合が容易となり、割り当てられたメモリーへのポインター操作が完全にサポートされます。

• パフォーマンスとプログラマーの利便性を適切に選択するため、割り当ての所有権とアクセスの可能性を細かく制御できます。
• SYCL デバイスとホスト間で、複数の割り当てを自動的に移行するより単純なプログラミング・モデルです。
4.8 節を参照してください。

ワークグループ (work-group)
SYCL work-group (sycl::group クラス) は、単一の計算ユニットで実行される work-item のコレクションを表現します。グループ内のwork-item は、同一カーネル・インスタンスを実行し、ローカルメモリーと work-group 関数を共有します。sycl::group クラスの詳細については、4.9.1.7 節を参照してください。

ワークグループ・バリア (work-group barrier)work-group 内のすべての work-item のグループバリアです。

ワークグループ・メモリー・フェンス (work-group mem-fence)
work-group 内のすべての work-item のメモリーフェンスです。

ワークグループ id (work-group id)
OpenCL と同様に、SYCL カーネルは work-group で実行されます。グループ ID は、work-item が実行される work-group の ID です。グループ ID は、次元ごとに 0 から始まる 1 次元、2 次元、または 3 次元の値です。

用語集 | 443

SYCL 2020 リビジョン 6 - 用語集

ワークグループ・レンジ (work-group range)
グループレンジは、すべての次元の work-group のサイズです。

ワーク項目 (work-item)SYCL work-item は、コマンドによってデバイス上で起動されたカーネルの並列実行コレクションの work-item を表現します。workitem は、計算ユニットで実行される work-group の一部として、1 つまたは複数の処理要素で実行されます。work-item は、グローバ
ル id または work-group id と work-group 内の ローカル id の組み合わせによって、ほかの work-item とは区別されます。

444 | 用語集