英文:
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<Buffer<uint8_t>> input{"input", 2};
Output<Buffer<uint8_t>> output{"output", 2};
In generate method I defined following algorithm:
output(c,x) = Halide::cast<uint8_t> (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<uint8_t> (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<uint8_t> 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 "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);
// define algorithm
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);
}
};
// 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<uint8_t> out(buffer_out, {{0,6,1}, {0,size/4,6}});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论