3

私は Halide を使い始めており、Python 環境から使用しています。その Python 環境内でデータは Numpy 配列として渡されますが、これは実際には別の場所で定義された C++ 配列のエイリアスです。

ただし、Halide 関数の呼び出しを使用すると、エラーが発生します。

制約違反: img.stride.0 (520) == 1 (1)
中止 (コアダンプ)

これは、numpy 配列を Fortran レイアウト配列にコピーすることで「解決」できます。

img=np.copy(img,order="F")
res=np.copy(res,order="F")

img と res を使用して、入力画像と出力画像を作成します。ただし、これには余分なコピー操作が含まれることに注意してください。これは、グローバル メモリ アクセス全体にとって非常に悪いことです。

この問題を回避するにはどうすればよいですか? 私が考えていた方法は、配列に Fortran レイアウトがあり、インデックスが適切に切り替えられていることを実際に Python に伝えることです....ただし、現在 PyArray_SimpleNewFromData を使用して Python 配列を取得し (実際にデータをコピーすることなく)、結果は次のようになります。 C スタイルの配列。

4

2 に答える 2

2

Halide はネイティブに行優先のストレージを想定していますが、次のようにインデックスを付けます: im(col, row)... これは、画像を行列として扱ったり、C で 2D 配列を使用したりすることに慣れている人にとっては、列優先のストレージに非常によく似ています。

したがって、Halide の概念に一致するようにインデックスを変更するか、Halide にメモリ レイアウトが逆であることを伝える (stride(0) が大きい) ことを選択できます。

ここに密接に関連するトピックをカバーするチュートリアルがあります: http://halide-lang.org/tutorials/tutorial_lesson_16_rgb_generate.html

2D 入力と Funcs の短いバージョンは次のとおりです。

image_param.set_stride(0, Expr()).set_stride(1, 1);
output_func.output_buffer().set_stride(0, Expr()).set_stride(1, 1);

最初の set_stride 呼び出しは、次元 0 のストライドの制約を解除し、2 番目の呼び出しは、次元 1 のストライドが 1 であると仮定できることを Halide に伝えます。それはメモリに密集しています:

f(i, j) = ...
f.vectorize(j, 4)
于 2015-12-23T19:08:55.643 に答える
0

問題はPyArray_SimpleNewFromData、ホスト C++ コードでは配列が Fortran スタイルであるデータから C スタイルの ndarray を作成したことです。解決策は、作成された直後に ndarray を変換することです。これは、次のようなコードで実行できます。

def swap(img):
    (sh1,sh2)=img.shape
    (st1,st2)=img.strides
    img.shape=(sh2,sh1)
    img.strides=(st2,st1)

この後、Halide 内では通常、ゼロ (x) 次元でベクトル化できます。

于 2015-12-24T11:57:40.827 に答える