0

これが私の最初の投稿なので、何か間違っていたらごめんなさい:)。頑張ります。

私は現在、HDR 画像処理プログラムに取り組んでおり、Halide を使用してベース TMO を実装するつもりはありません。問題は、すべての画像がfloat配列として表されていることです(b1、g1、r1、a1、b2、g2、r2、a2、...のような順序で)。Halide を使用して画像を処理するには、Halide::Image クラスが必要です。問題は、それらのデータをそこに渡す方法がわからないことです。

誰でも助けることができますか、同じ問題を抱えていて答えを知っていますか?

編集:

ついに手に入れました!ジェネレーターの入力バッファーと出力バッファーにストライドを設定する必要があります。助けてくれてありがとう:-)

編集:

私は2つの異なる方法を試しました:

int halideOperations( float data[] , int size, int width,int heighy ) 
{ 
buffer_t input_buf = { 0 }; 
input_buf.host = &data[0]; 
} 

また:

int halideOperations( float data[] , int size, int width,int heighy ) 
{ 
Halide::Image(Halide::Type::Float, x, y, 0, 0, data);
}

Halide.h ファイルを編集して uint8_t * host を float_t * host に変更することを考えていましたが、それは良い考えではないと思います。

編集:

float 画像 (RGBA) で以下のコードを使用してみました:

AOT 関数の生成:

int main(int arg, char ** argv)
{
    Halide::ImageParam img(Halide::type_of<float>(), 3);
    Halide::Func f;
    Halide::Var x, y, c;
    f(x, y, c) = Halide::pow(img(x,y,c), 2.f);

    std::vector<Halide::Argument> arguments = { img };
    f.compile_to_file("function", arguments);
    return 0;
}

適切なコードの呼び出し:

int halideOperations(float data[], int size, int width, int height)
{
    buffer_t  output_buf = { 0 };
    buffer_t buf = { 0 };
    buf.host = (uint8_t *)data; 
    float * output = new float[width * height * 4];
    output_buf.host = (uint8_t*)(output);
    output_buf.extent[0] = buf.extent[0] = width; 
    output_buf.extent[1] = buf.extent[1] = height; 
    output_buf.extent[2] = buf.extent[2] = 4;
    output_buf.stride[0] = buf.stride[0] = 4;
    output_buf.stride[1] = buf.stride[1] = width * 4;
    output_buf.elem_size = buf.elem_size = sizeof(float);

    function(&buf, &output_buf);

    delete output;
    return 1;
}

残念ながら、msg でクラッシュしました:

 Error: Constraint violated: f0.stride.0 (4) == 1 (1)

この行に何か問題があると思います: output_buf.stride[0] = buf.stride[0] = 4 ですが、何を変更すればよいかわかりません。任意のヒント?

4

2 に答える 2

1

buffer_t を直接使用している場合は、ホストに割り当てられたポインターを uint8_t * にキャストする必要があります。

buf.host = (uint8_t *)&data[0]; // Often, can be just "(uint8_t *)data"

これは、Ahead-Of-Time (AOT) コンパイルを使用していて、Halide を直接呼び出すコードの一部としてデータが割り当てられていない場合に実行したいことです。(以下で説明する他のメソッドは、ストレージの割り当てを制御するため、渡されたポインターを取得できません。)

Halide::Image または Halide::Tools::Image を使用している場合、型キャストは内部で処理されます。上記の Halide::Image のコンストラクターは存在しません。Halide::Image は、基になるデータ型がテンプレート パラメーターであるテンプレート クラスであるためです。

Halide::Image<float> image_storage(width, height, channels);

これにより、データが平面レイアウトで保存されることに注意してください。Halide::Tools::Image は似ていますが、インターリーブ レイアウトを行うオプションがあります。(個人的には、小規模なテスト プログラム以外ではこれらのいずれも使用しないようにしています。これらすべてを合理化するための長期的な計画があり、任意の次元の buffer_t ブランチがマージされた後に進められます。また、Halide::Image には libHalide.a が必要であることに注意してください。 Halide::Tools::Image がリンクされておらず、 common/halide_image.h をインクルードすることによってのみヘッダー ファイルである場所にリンクされます。)

Just-In-Time (JIT) コンパイルで役立つ buffer_t のラッパーである Halide::Buffer クラスもあります。ストレージに渡されたものを参照でき、テンプレート化されていません。ただし、私の推測では、buffer_t を直接使用し、ホストを割り当てるために型キャストが必要なだけです。また、buffer_t の elem_size フィールドを必ず「sizeof(float)」に設定してください。

インターリーブされた float バッファーの場合、次のような結果になります。

buffer_t buf = {0};
buf.host = (uint8_t *)float_data; // Might also need const_cast
// If the buffer doesn't start at (0, 0), then assign mins
buf.extent[0] = width; // In elements, not bytes
buf.extent[1] = height; // In elements, not bytes
buf.extent[2] = 3; // Assuming RGB
// No need to assign additional extents as they were init'ed to zero above
buf.stride[0] = 3; // RGB interleaved
buf.stride[1] = width * 3; // Assuming no line padding
buf.stride[2] = 1; // Channel interleaved
buf.elem_size = sizeof(float);

また、Halide コード自体の境界にも注意を払う必要があります。これについては、tutorial/lesson_16_rgb_generate.cpp の set_stride とバインドされた呼び出しを参照することをお勧めします。

于 2016-04-24T18:47:24.620 に答える
0

上記の Zalman の回答に加えて、以下のように Halide 関数を定義するときに、入力と出力のストライドも指定する必要があります。

int main(int arg, char ** argv)
{
    Halide::ImageParam img(Halide::type_of<float>(), 3);
    Halide::Func f;
    Halide::Var x, y, c;
    f(x, y, c) = Halide::pow(img(x,y,c), 2.f);

    // You need the following
    f.set_stride(0, f.output_buffer().extent(2));
    f.set_stride(1, f.output_buffer().extent(0) * f.output_buffer().extent(2));
    img.set_stride(0, img.extent(2));
    img.set_stride(1, img.extent(2) *img.extent(0));
    // <- up to here

    std::vector<Halide::Argument> arguments = { img };
    f.compile_to_file("function", arguments);
    return 0;
}

その後、コードが実行されます。

于 2016-11-17T23:37:13.437 に答える