在多次调用时,查找表索引的输入值的计算是常量,因此我预先计算了'indexToLut‘的内容。然而,这也意味着在这里不能对该缓冲区中的值进行检查。LUT本身只有17个元素。
#define LUT_SIZE 17 /* Size in each dimension of the 4D LUT */
class ApplyLut : public Halide::Generator<ApplyLut> {
public:
// We declare the Inputs to the Halide pipeline as public
// member variables. They'll appear in the signature of our generated
// function in the same order as we declare them.
Input < Buffer<uint8_t>> Lut { "Lut" , 1}; // LUT to apply
Input < Buffer<int>> indexToLut { "indexToLut" , 1}; // Precalculated mapping of uint8_t to LUT index
Input < Buffer<uint8_t >> inputImageLine { "inputImageLine" , 1}; // Input line
Output< Buffer<uint8_t >> outputImageLine { "outputImageLine", 1}; // Output line
void generate();
};
HALIDE_REGISTER_GENERATOR(ApplyLut, outputImageLine)
void ApplyLut::generate()
{
Var x("x");
outputImageLine(x) = Lut(indexToLut(inputImageLine(x)));
inputImageLine .dim(0).set_min(0); // Input image sample index
outputImageLine.dim(0).set_bounds(0, inputImageLine.dim(0).extent()); // Output line matches input line
Lut .dim(0).set_bounds(0, LUT_SIZE); //iccLut[...]: , limited number of values
indexToLut .dim(0).set_bounds(0, 256); //chan4_offset[...]: value index: 256 values
}在问题Are there any restrictions with LUT: unbounded way in dimension中,已经指出这样的问题可以通过使用'clamp‘功能来解决。
这会将表达式更改为
outputImageLine(x) = Lut(clamp(indexToLut(inputImageLine(x)), 0, LUT_SIZE));但是,生成的代码显示以下表达式
outputImageLine[outputImageLine.s0.x] = Lut[max(min(indexToLut[int32(inputImageLine[outputImageLine.s0.x])], 17), 0)]我认为这意味着执行将进行最小/最大计算,在我的例子中可以忽略,因为我知道indexToLut的所有值都被限制为0..16。在这种情况下,有没有办法避免执行开销?
发布于 2019-12-14 06:01:50
您可以使用unsafe_promise_clamped而不是clamp来保证输入按照您所描述的方式进行限制。它可能不会更快-与间接加载相比,整数索引上的min和max非常便宜。
https://stackoverflow.com/questions/59318597
复制相似问题