输入缓冲区的类型为Halide::Runtime::Buffer,由生成器修改。

huangapple go评论91阅读模式
英文:

input buffer of type Halide::Runtime::Buffer gets modified by generator

问题

我有一个具有输入和输出的生成器:

Input<Buffer<uint8_t>> input{"input", 2};
Output<Buffer<uint8_t>> output{"output", 2};

在generate方法中,我定义了以下算法:

output(c, x) = Halide::cast<uint8_t>(input(mux(c, {1,0,2,3,0,2}), x));

问题是,当我从主程序传递输入和输出缓冲区时,我得到了期望的输出,但输入缓冲区也被修改了,我希望避免这种情况。我尝试创建函数然后应用算法,但效果相同:

Func decode;
Func in;
in(c, x) = input(c, x);
decode(c, x) = Halide::cast<uint8_t>(in(mux(c, {1,0,2,3,0,2}), x));
output(c, x) = decode(c, x);

我还尝试从Input<Buffer<uint8_t>> input{"input", 2}创建输入缓冲区的副本:

in(c, x) = input(c, x);
Halide::Buffer<uint8_t> in_copy = in.realize({input.dim(0).extent(), input.dim(1).extent()});

但这会导致"Unhandled exception: Error: Buffer argument input is nullptr"的异常,这是可以理解的。您有什么建议如何避免输入缓冲区的变异?

@Alex要求发布一个可编译的生成器,以下是一个使用函数的版本:

#include "Halide.h"

using namespace Halide;

class Yuv422Decoder : public Halide::Generator<Yuv422Decoder> {
public:

    Input<Buffer<uint8_t>> input{"input", 2};
    Output<Buffer<uint8_t>> output{"output", 2};

    Var c, x, xo, xi, co, ci;

    void generate() {
        Func decode;
        Func in;
        in(c, x) = input(c, x);
        // 定义算法
        decode(c, x) = Halide::cast<uint8_t>(in(mux(c, {1,0,2,3,0,2}), x));
        output(c, x) = decode(c, x);
    }

    void schedule() {
        output.bound_extent(c, 6);
        output.split(x, xo, xi, input.dim(1).extent() / 8);
        output.parallel(xo, 2);
        output.parallel(xi, 2);
        output.unroll(c);
        output.vectorize(xi, 128);
    }
};

// 使用此宏创建一个您可以在程序中调用的函数
HALIDE_REGISTER_GENERATOR(Yuv422Decoder, yuv422decoder);

希望这能帮助您避免输入缓冲区的变异。

英文:

I have a generator that has input and output:

Input&lt;Buffer&lt;uint8_t&gt;&gt; input{&quot;input&quot;, 2};
Output&lt;Buffer&lt;uint8_t&gt;&gt; output{&quot;output&quot;, 2};

In generate method I defined following algorithm:

output(c,x) = Halide::cast&lt;uint8_t&gt; (input(mux(c, {1,0,2,3,0,2}), x));

The problem is that when I pass input and output buffer from main program I get the desired output but input buffer gets also modified which I would like to avoid. I tried to make function and then apply algorithm but I have same effect:

    Func decode;
    Func in;
    in(c,x) = input(c,x);
    decode(c,x) = Halide::cast&lt;uint8_t&gt; (in(mux(c, {1,0,2,3,0,2}), x));
    output(c,x) = decode(c,x);
    ...

I also tried to create copy of input buffer from Input<Buffer<uint8_t>> input{"input", 2} like:

in(c,x) = input(c,x);
Halide::Buffer&lt;uint8_t&gt; in_copy = in.realize({Halide::Internal::as_const_int(input.dim(0).extent()), Halide::Internal::as_const_int(input.dim(1).extent())});

but this results in Unhandled exception: Error: Buffer argument input is nullptr which is understandable. Do You have any suggestion how to avoid input buffer mutation?
@Alex asked to post compile-able generator so here is a version with using the functions

#include &quot;Halide.h&quot;

using namespace Halide;

class Yuv422Decoder : public Halide::Generator&lt;Yuv422Decoder&gt; {
public:

    Input&lt;Buffer&lt;uint8_t&gt;&gt; input{&quot;input&quot;, 2};
    Output&lt;Buffer&lt;uint8_t&gt;&gt; output{&quot;output&quot;, 2};

    Var c,x,xo,xi,co,ci;

    void generate() {
        Func decode;
        Func in;
        in(c,x) = input(c,x);
        // define algorithm
        decode(c,x) = Halide::cast&lt;uint8_t&gt; (in(mux(c, {1,0,2,3,0,2}), x));
        output(c,x) = decode(c,x);       
    }

    void schedule() {
        output.bound_extent(c,6);
        output.split(x, xo, xi, input.dim(1).extent()/8);
        output.parallel(xo,2);
        output.parallel(xi,2);
        output.unroll(c);
        output.vectorize(xi,128);
       }
    };

// Use this macro to create function that you can call in your program

HALIDE_REGISTER_GENERATOR(Yuv422Decoder, yuv422decoder);

答案1

得分: 0

问题出在输出缓冲区的大小上。我将其加倍,现在输入缓冲区不再发生变异。我不确定当输出缓冲区的大小太小时,究竟会发生什么,但无论如何,最终这是编程错误。

uint8_t* buffer_out = new uint8_t [2*size];
Runtime::Buffer<uint8_t> out(buffer_out, {{0,6,1}, {0,size/4,6}});
英文:

Problem was in size of the output buffer. I doubled it and now I don't have mutation of input buffer. I am not sure how exactly this happens when size of the output buffer is too small but anyhow it was programming mistake in the end.

uint8_t* buffer_out = new uint8_t [2*size];
Runtime::Buffer&lt;uint8_t&gt; out(buffer_out, {{0,6,1}, {0,size/4,6}});

huangapple
  • 本文由 发表于 2023年2月14日 19:18:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447055.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定