この記事は、https://www.oneapi.io/spec/ で 2023年9月14日に公開された『oneAPI 1.3 Provisional Specification Rev. 1』 (HTML、PDF) をベースにしています。原文は2000 ページ近くあり、翻訳の時間とリソースも限られるため、全文翻訳ではなく、記事形式で区切った仕様とその解説を提供することにしました。
この回では、『oneAPI 1.3 Provisional Specification Rev. 1』の「oneDNN」の「Reorder」と「Resampling」の節を取り上げています。
リオーダー
リオーダー・プリミティブは、2 つのメモリー・オブジェクト間でデータをコピーします。このプリミティブは、通常、データがメモリーに配置される方法を変更する際に使用されます。
リオーダー・プリミティブは、異なるメモリー形式間でデータをコピーしますが、数学的観点からはテンソルを変更することはありません。変数名は標準の規則 (英語) に従います。
、 の場合
「はじめに」で説明したように、最高のパフォーマンスを達成するため、一部のプリミティブ (畳み込みなど) では最適化されたメモリー形式と呼ばれる特殊なメモリー形式が求められます。最適化されたメモリー形式では、データが保存されているメモリー形式と一致する場合としない場合があります。この場合、ユーザーはリオーダー・プリミティブを使用してメモリー形式間でデータをコピー (並べ替え) できます。
属性と post-ops を使用して、ユーザーはリオーダー・プリミティブによりデータを量子化することもできます (必要に応じてメモリー形式を同時に変更します)。
実行引数
実行時に入力と出力は、次の表で示す実行引数インデックスにマップする必要があります。
プリミティブの入力/出力 | 実行引数インデックス |
---|---|
src |
DNNL_ARG_FROM |
dst |
DNNL_ARG_TO |
操作の詳細
リオーダー・プリミティブでは、ソースとデスティネーション・テンソルは同一形状である必要があります。暗黙のブロードキャストはサポートされません。
ほとんどの場合、リオーダーは任意のソースとデスティネーションのメモリー形式とデータタイプで処理できるはずですが、一部の組み合わせは実装されていない可能性があります。次に例を示します。
非プレーンメモリー形式の重み間の並べ替え実装が制限される場合があります (ただし、実際に発生した場合は、バグとして oneDNN チームに報告してください)。
ある Winograd 形式の重みを他の Winograd 形式の重みに並べ替えることはできません。
#dnnl_s8 ソースデータタイプの畳み込み量子化された重みは、#dnnl_f32 データタイプに逆量子化することはできません。
この問題を軽減するため、ユーザーはオリジナルのプレーンメモリー形式とデータタイプから、選択されたデータタイプの最適化された形式への並べ替えを実装する必要があります。
サポートされるデータタイプ
リオーダー・プリミティブは、ソースとデスティネーションの任意のデータタイプをサポートします。
データをあるデータタイプからそれより小さなデータタイプへ変換する場合、飽和が必要になります。次に例を示します。
reorder(src={1024, data_type=f32}, dst={, data_type=s8}) // dst == {127} reorder(src={-124, data_type=f32}, dst={, data_type=u8}) // dst == {0}
データ表現
リオーダー・プリミティブは任意のデータテンソルで機能します。論理的な次元については特別な意味はありません。
post-ops と属性
リオーダー・プリミティブは、次の属性と post-ops をサポートする必要があります。
タイプ | 操作 | 説明 | 制限事項 |
---|---|---|---|
Attribute | スケール |
対応するテンソルにスケールを設定します | Int8 計算のみ |
Attribute | ゼロポイント |
対応するテンソルにゼロポイントを設定します | Int8 計算のみ |
post-op | 累計 |
演算結果を上書きせずに、デスティネーション・テンソルに加算します。 |
次に疑似コードを示します。
reorder( src = {dims={N, C, H, W}, data_type=dt_src, memory_format=fmt_src}, dst = {dims={N, C, H, W}, data_type=dt_dst, memory_format=fmt_dst}, attr ={ output_scale=alpha, post-ops = { sum={scale=beta} }, })
これは次の操作につながります。
注: 中間操作は、単精度浮動小数点データタイプを使用して実行されます。
API
API については、こちら (英語) をご覧ください。
リサンプリング
リサンプリング・プリミティブは、1D、2D、または 3D 空間データの順方向または逆方向のリサンプリングリング操作を計算します。リサンプリングは、サポートされる補間アルゴリズムを使用して、オリジナルのテンソルの空間スケーリングを行います。
- 近傍法
- 線形 (または 2D 空間テンソルでは双線形、3D 空間テンソルでは三線形)
リサンプリング操作は、それぞれの空間次元のソーステンソルとスケーリング係数によって定義されます。アップサンプリングとダウンサンプリングは、すべてのスケーリング係数が 1 より大きい (アップサンプリング)、または小さい (ダウンサンプリング) 場合に適用されるリサンプリングの別名です。
リサンプリング操作は次の式で定義されます。高次元と低次元のケースでは、一般化が容易な 2D 空間データの式のみを示します。変数名は標準の規則 (英語) に従います。
src
と dst
をそれぞれ N × C × IH × IW
と N × C × OH × OW
テンソルとします。 と は、それぞれの空間次元のスケーリング係数を定義します。
次の式は、oneDNN が近傍法および双一次補間法のリサンプリングを計算する方法を示します。式を単純にするため、以下を前提とします。
- ih<0 または iw<0 の場合、src(n,ic,ih,iw)=0
- ih≥IH の場合、src(n,ic,ih,iw)=src(n,ic,IH−1,iw)
- iw≥IW の場合、src(n,ic,ih,iw)=src(n,ic,ih,IW−1)
順方向 (前方)
近傍リサンプリング
dst(n,c,oh,ow)=src(n,c,ih,iw)
説明:
双一次リサンプリング
説明:
順方向トレーニングと順方向推論の違い
forward_training
と forward_inference
伝播の種類に違いはありません。
逆方向 (後方)
逆方向伝播は、diff_dst
に基づいて diff_src
を計算します。
実行引数
実行時に入力と出力は、次の表で示す実行引数インデックスにマップする必要があります。
操作の詳細
リサンプリングの実装では、任意のデータタグ (
nchw
、nhwc
など) のデータをサポートしますが、src
とdst
のメモリータグは同一であると期待されます。リサンプリング・プリミティブは、dst
およびdiff_src
メモリータグany
をサポートし、ソース形式に基づいてデスティネーション形式を定義します。リサンプリング記述子は、ソースとデスティネーションのメモリー記述子、ソース記述子と浮動小数点係数のみ、またはソースとデスティネーションのメモリー記述子と係数を指定して作成できます。ユーザーがデスティネーション記述子を指定しない場合、デスティネーションの次元は次の係数から推測されます。
注: リサンプリング・アルゴリズムでは、 の関係によって定義された係数が使用されますが、これはユーザーが渡す係数と必ずしも一致するわけではありません。
サポートされるデータタイプ
リサンプリング・プリミティブは、ソース・メモリー・オブジェクトとデスティネーション・メモリー・オブジェクトのデータタイプで次の組み合わせをサポートします。
注: この節では、可読性のためデータタイプの名称を短縮しています。例えば、dnnl::memory::data_type::f32
は f32
に短縮されます。
post-ops と属性
リサンプリング・プリミティブは post-ops や属性をサポートしません。
API
API については、こちら (英語) をご覧ください。
法務上の注意書き
The content of this oneAPI Specification is licensed under the Creative Commons Attribution 4.0 International License (英語). Unless stated otherwise, the sample code examples in this document are released to you under the MIT license (英語).
This specification is a continuation of Intel’s decades-long history of working with standards groups and industry/academia initiatives such as The Khronos Group*, to create and define specifications in an open and fair process to achieve interoperability and interchangeability. oneAPI is intended to be an open specification and we encourage you to help us make it better. Your feedback is optional, but to enable Intel to incorporate any feedback you may provide to this specification, and to further upstream your feedback to other standards bodies, including The Khronos Group SYCL* specification, please submit your feedback under the terms and conditions below. Any contribution of your feedback to the oneAPI Specification does not prohibit you from also contributing your feedback directly to other standard bodies, including The Khronos Group under their respective submission policies.
By opening an issue, providing feedback, or otherwise contributing to the specification, you agree that Intel will be free to use, disclose, reproduce, modify, license, or otherwise distribute your feedback at its sole discretion without any obligations or restrictions of any kind, including without limitation, intellectual property rights or licensing obligations.
This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice.
© Intel Corporation. Intel、インテル、Intel ロゴ、その他のインテルの名称やロゴは、Intel Corporation またはその子会社の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。