Halide で extern 関数を使用しようとしています。私の文脈では、GPUでやりたいです。
opencl ステートメントを使用して AOT コンパイルでコンパイルします。もちろん、opencl は引き続き CPU を使用できるので、これを使用します。
halide_set_ocl_device_type("gpu");
今のところ、すべてが compute_root() でスケジュールされています。
最初の質問ですが、compute_root() と OpenCL gpu を使用した場合、私のプロセスは CopyHtoD と DtoH を使用してデバイス上で計算されますか? (または、ホスト バッファ上にあります)
2 番目の質問は、extern 関数に関連しています。一部のアルゴリズムが Halide にないため、一部の extern 呼び出しを使用します。外部呼び出し:
foo.define_extern("cool_foo", args, Float(32), 4);
外部取得: extern "C" int cool_foo(buffer_t * in, int w, int h, int z, buffer_t * out){ .. }
しかし、cool_foo 関数では、私の buffer_t はホスト メモリにのみロードされます。dev アドレスは 0 (デフォルト) です。
アルゴリズムの前にメモリをコピーしようとすると:
halide_copy_to_dev(NULL, &in);
それは何もしません。
デバイスメモリのみを利用可能にする場合:
in.host = NULL;
ホスト ポインタは null ですが、デバイス アドレスはまだ 0 です。
(私の場合、dev_dirty は true で、host_dirty は false)
何か案が?
EDIT(dshaletに答えるために)
私のコードの構造は次のとおりです。
CPU でデータを正しく解析します。--> GPU にバッファを送信 (halode_copy_to_dev を使用...) --> Halide 構造体に入力し、パラメータを読み取り、境界条件を追加 --> extern 関数に移動 -->...
extern 関数に有効な buffer_t がありません。すべてを compute_root() でスケジュールしますが、HL_TARGET=host-opencl を使用し、ocl を gpu に設定します。Halide に入る前に、デバイスのアドレスを読み取ることができ、問題ありません。
これが私のコードです:
Halide の前は、すべてが CPU のもの (ポインター) であり、それを GPU に転送しました。
buffer_t k = { 0, (uint8_t *) k_full, {w_k, h_k, num_patch_x * num_patch_y * 3}, {1, w_k, w_k * h_k}, {0}, sizeof(float), };
#if defined( USEGPU )
// Transfer into GPU
halide_copy_to_dev(NULL, &k);
k.host_dirty = false;
k.dev_dirty = true;
//k.host = NULL; // It's k_full
#endif
halide_func(&k)
インサイド ハライド:
ImageParam ...
Func process;
process = halide_sub_func(k, width, height, k.channels());
process.compute_root();
...
Func halide_sub_func(ImageParam k, Expr width, Expr height, Expr patches)
{
Func kBounded("kBounded"), kShifted("kShifted"), khat("khat"), khat_tuple("khat_tuple");
kBounded = repeat_image(constant_exterior(k, 0.0f), 0, width, 0, height, 0, patches);
kShifted(x, y, pi) = kBounded(x + k.width() / 2, y + k.height() / 2, pi);
khat = extern_func(kShifted, width, height, patches);
khat_tuple(x, y, pi) = Tuple(khat(0, x, y, pi), khat(1, x, y, pi));
kShifted.compute_root();
khat.compute_root();
return khat_tuple;
}
外側のハライド (Extern 関数):
inline ....
{
//The buffer_t.dev and .host are 0 and null. I expect a null from the host, but the dev..
}