2016-08-22 5 views
1

私のハライドプログラムをコンパイルして、後で別の画像でコードで数回使用するようにしています。しかし、私は何かが間違っていると思う、誰でも私を修正することはできますか? まず、私は実行するためのハロゲン化物関数を作成します。ポインタでハライドジットコンパイル

void m_gammaFunctionTMOGenerate() 
{ 
    Halide::ImageParam img(Halide::type_of<float>(), 3); 
    img.set_stride(0, 4); 
    img.set_stride(2, 1); 
    Halide::Var x, y, c; 
    Halide::Param<float> key, sat, clampMax, clampMin; 
    Halide::Param<bool> cS; 
    Halide::Func gamma; 
    // algorytm 
    //img.width() , img.height(); 
    if (cS.get()) 
    { 
     float k1 = 1.6774; 
     float k2 = 0.9925; 
     sat.set((1 + k1) * pow(key.get(), k2)/(1 + k1 * pow(key.get(), k2))); 
    } 
    Halide::Expr luminance = img(x, y, 0) * 0.072186f + img(x, y, 1) * 0.715158f + img(x, y, 2) * 0.212656f; 
    Halide::Expr ldr_lum = (luminance - clampMin)/(clampMax - clampMin); 
    Halide::clamp(ldr_lum, 0.f, 1.f); 
    ldr_lum = Halide::pow(ldr_lum, key); 
    Halide::Expr imLum = img(x, y, c)/luminance; 
    imLum = Halide::pow(imLum, sat) * ldr_lum; 
    Halide::clamp(imLum, 0.f, 1.f); 
    gamma(x, y, c) = imLum; 
    // rozkład 
    gamma.vectorize(x, 16).parallel(y); 

    // kompilacja 
    auto & obuff = gamma.output_buffer(); 
    obuff.set_stride(0, 4); 
    obuff.set_stride(2, 1); 
    obuff.set_extent(2, 3); 
    std::vector<Halide::Argument> arguments = { img, key, sat, clampMax, clampMin, cS }; 
    m_gammaFunction = (gammafunction)(gamma.compile_jit()); 

} 

店にそれを:

typedef int(*gammafunction)(buffer_t*, float, float, float, float, bool, buffer_t*); 
gammafunction m_gammaFunction; 

その後、私はそれを実行しよう:

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

// Run the pipeline 
int error = m_photoFunction(&buf, params[0], &output_buf); 

しかし、それは動作しません。.. エラー:

Exception thrown at 0x000002974F552DE0 in Viewer.exe: 0xC0000005: Access violation executing location 0x000002974F552DE0. 

If there is a handler for this exception, the program may be safely continued. 

編集:

ここでは、機能を実行するための私のコードです:

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

// Run the pipeline 
int error = m_gammaFunction(&buf, params[0], params[1], params[2], params[3], params[4] > 0.5 ? true : false, &output_buf); 

if (error) { 
    printf("Halide returned an error: %d\n", error); 
    return -1; 
} 

memcpy(output, data, size * sizeof(float)); 

誰もがそれで私を助けることができますか?

編集:私は私が間違って何をしていたかが分かった@KhouriGiordanoに

感謝。実際、私はAOTコンパイルからこのコードに切り替えました。だから今私のコードは以下のようになります。

class GammaOperator 
{ 
public: 
    GammaOperator(); 

    int realize(buffer_t * input, float params[], buffer_t * output, int width); 
private: 

    HalideFloat m_key; 
    HalideFloat m_sat; 
    HalideFloat m_clampMax; 
    HalideFloat m_clampMin; 
    HalideBool m_cS; 

    Halide::ImageParam m_img; 
    Halide::Var x, y, c; 
    Halide::Func m_gamma; 
}; 


GammaOperator::GammaOperator() 
    : m_img(Halide::type_of<float>(), 3) 
{ 

    Halide::Expr w = (1.f + 1.6774f) * pow(m_key.get(), 0.9925f)/(1.f + 1.6774f * pow(m_key.get(), 0.9925f)); 
    Halide::Expr sat = Halide::select(m_cS, m_sat, w); 

    Halide::Expr luminance = m_img(x, y, 0) * 0.072186f + m_img(x, y, 1) * 0.715158f + m_img(x, y, 2) * 0.212656f; 
    Halide::Expr ldr_lum = (luminance - m_clampMin)/(m_clampMax - m_clampMin); 
    ldr_lum = Halide::clamp(ldr_lum, 0.f, 1.f); 
    ldr_lum = Halide::pow(ldr_lum, m_key); 
    Halide::Expr imLum = m_img(x, y, c)/luminance; 
    imLum = Halide::pow(imLum, sat) * ldr_lum; 
    imLum = Halide::clamp(imLum, 0.f, 1.f); 
    m_gamma(x, y, c) = imLum; 

} 

int GammaOperator::realize(buffer_t * input, float params[], buffer_t * output, int width) 
{ 
    m_img.set(Halide::Buffer(Halide::type_of<float>(), input)); 
    m_img.set_stride(0, 4); 
    m_img.set_stride(1, width * 4); 
    m_img.set_stride(2, 4); 
    // algorytm 
    m_gamma.vectorize(x, 16).parallel(y); 

    //params[0], params[1], params[2], params[3], params[4] > 0.5 ? true : false 
    //{ img, key, sat, clampMax, clampMin, cS }; 
    m_key.set(params[0]); 
    m_sat.set(params[1]); 
    m_clampMax.set(params[2]); 
    m_clampMin.set(params[3]); 
    m_cS.set(params[4] > 0.5f ? true : false); 
    //// kompilacja 
    m_gamma.realize(Halide::Buffer(Halide::type_of<float>(), output)); 
    return 0; 
} 

と私はそのようにそれを使用します。

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

    // Run the pipeline 

    int error = s_gamma->realize(&buf, params, &output_buf, width); 

それはまだコンソールで情報をm_gamma.realize機能にクラッシュさ:

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

すべての 'ImageParam'は暗黙の' set_stride(0,1) 'で始まります。 'set_min()'、 'set_extent()'、 'set_stride()'メンバ関数は渡されたバッファによって満たされなければならない制約です。あなたがやっていることと 'set_stride(0、Expr())'を合わせて制約を削除するには 'set_stride(0,4)'を使います。 –

+0

また、あなたが設定したmin、extent、strideは 'Expr'なので、widthやheightのような' Param'値に依存することがあります。 –

+0

私はすでにそれを持っています: 'm_img.set_stride(0、4);'それはうまく動作しません... –

答えて

1

Halide::Param::get()を使用すると、に電話するときにParamオブジェクトから(デフォルトの0)値を抽出します。あなたが生成された関数を呼び出すときに指定されたパラメータ値を使用したい場合は、単にgetを呼び出すことなく、それを使用し、それが暗黙のうちにExprに変換する必要があります。

Paramはブール値に変換できないため、ifのハライド方法はHalide::select()です。

クランプされた戻り値Halide::clamp()を使用していません。

cSはハライドコードで使用されているとは限りませんが、Cコードのみが使用されています。あなたのJITの問題に今

。 AOTコンパイルを始めてJITに切り替えたようです。

あなたはstd::vector<Halide::Argument>を作りますが、どこにも渡しません。ハライドはどのように使用したいのですか?ParamFuncを見て、ImageParamParamオブジェクトへの参照を見つけます。

Paramがどのような順序を期待していますか?あなたはこれを支配しません。私はHL_GENBITCODE=1を定義することによって、ビットコードをダンプすることができましたし、その後、あなたの関数を参照してくださいllvm-disであることを表示:

int gamma 
    (buffer_t *img 
    , float clampMax 
    , float key 
    , float clampMin 
    , float sat 
    , void *user_context 
    , buffer_t *result 
    ); 
  • 使用gamma.realize(Halide::Buffer(Halide::type_of<float>(), &output_buf))代わりgamma.compile_jit()を使用して、適切に生成された関数を呼び出すようにしようとします。 1時間の使用のための

  • 利用Imageの代わりImageParam
  • Paramの代わりにExprを使用してください。単一JITコンパイルして繰り返し使用するために

  • 周りImageParamParamを保ち、Funcを実現する前にそれらを設定します。
+0

はい、申し訳ありませんが、間違ったコードを2番目に貼り付けて、最初の投稿を適切なものに編集します –