私の質問を組み立てるには:
任意のサイズの HxWxD 入力ボリュームが FxFxD フィルターで畳み込まれるカスタム畳み込み (CNN 用) を作成しています。D は 3 または 4 の場合もありますが、それ以上の場合もあります。私は RenderScript を初めて使用し、現在、将来使用できるフレームワークを作成することを目標にアプローチを調査しているため、すぐに非推奨になる可能性のある方法で API を使用することになりたくありません。私は現在 23 を目標にしていますが、ある時点で 18 ~ 19 に戻す必要があるかもしれません。これについては議論の余地があります。
3D Allocation を定義し、カーネルの in-parameter のタイプとして float を使用すると、カーネルは Z 軸に沿ってすべての要素を訪問するようです。このような:
カーネル:
void __attribute__((kernel)) convolve(float in, uint32_t x, uint32_t y, uint32_t z){
rsDebug("x y z: ", x, y, z);
}
ジャワ:
Allocation in;
Type.Builder tb = new Type.Builder(mRS, Element.F32(mRS));
Type in_type = tb.setX(W).setY(H).setZ(D).create();
in = Allocation.createTyped(mRS, in_type);
//...
mKonvoScript.forEach_convolve(in);
W=H=5 および D=3 の場合、3D ボリュームには 75 個のフロートがあります。プログラムを実行すると、75 個の出力が出力されます。
xy: {0.000000, 0.000000, 0.000000} xy: {1.000000, 0.000000, 0.000000} ... xy: {0.000000, 0.000000, 1.000000} xy: {1.000000, 0.000000, 00} ...
等
パターンは 3x25 回繰り返されます。
OTOH 参照は z 座標について不明であり、renderscript の答え: 'z' 座標へのアクセスは、z 座標パラメーターがサポートされていないことを示しています。
また、フィルターをカーネル内の rs_allocation 変数にバインドする必要があります。今私は持っています:
カーネル:
rs_allocation gFilter;
//...
float f = rsGetElementAt_float(gFilter, 1,2,3);
ジャワ:
Allocation filter;
Type filter_type = tb.setX(F).setY(F).setZ(D).create();
filter = Allocation.createTyped(mRS, filter_type);
これはうまくいくようです (コンパイル エラーや実行時エラーは発生しません)。しかし、バージョン 20 以降では 1D 割り当てのみをバインドできると述べている 2014 年の SE エントリがあり、これは私の結果と矛盾しています。
そこには矛盾した古い情報がたくさんあるので、内部の誰かがこれについてコメントし、持続可能性と最適性の両方の観点からアプローチを推奨してくれることを願っています.
(1) 渡された xyz 座標を使用して、バインドされた 3D 割り当てとの畳み込みを計算する必要がありますか? それとも、このアプローチはある時点で非推奨になるのでしょうか?
(2) これを行う方法は他にもあります。たとえば、すべての割り当てを 1D に再形成し、それらをカーネルに渡し、インデックス演算を使用できます。これにより、特定の値を互いに近くに配置することもできます。もう 1 つのアプローチは、入力 3D ボリュームを深さ 4 のブロックに分割し、型として float4 を使用することです。(1)を使用しても問題ないと仮定すると、最適化の観点から、他のアプローチとは対照的に(1)を使用することに不利な点はありますか?
(3)一般に、(1)のような「単純な」アプローチとは対照的に、最適性の理由から、問題をfloat3またはfloat4の深さに再定式化するなど、望ましいメモリレイアウトの定式化はありますか?