使用参数RDom简化重复计算

时间:2018-10-04 15:56:43

标签: halide

我正在尝试将Halide程序从每个操作具有恒定的滤镜大小的条件重写为所有滤镜都是参数化的条件。除了一项功能外,一切都进行顺利。这是有问题的函数片段:

Input<int> filter_size{"filter_size"};
//...
Halide::RDom filter_dom(-filter_size, filter_size * 2 + 1, -filter_size, filter_size * 2 + 1);
//...
Halide::Expr rdiff = G(x + filter_dom.x, y + filter_dom.y, 0) - G(x, y, 0);
Halide::Expr gdiff = G(x + filter_dom.x, y + filter_dom.y, 1) - G(x, y, 1);
Halide::Expr bdiff = G(x + filter_dom.x, y + filter_dom.y, 2) - G(x, y, 2);
Halide::Expr dw = Halide::exp(-0.5f * (rdiff * rdiff + gdiff * gdiff + bdiff * bdiff) * s_coeff)
                * gauss2d(filter_dom.x, filter_dom.y);
blf(x, y, c) = Halide::sum(img(x + filter_dom.x, y + filter_dom.y, c) * dw, "blf_sum_01")
                / Halide::sum(dw, "blf_sum_02");

有一个重复项dw,对于Halide::sum的每个阶段,很容易只计算一次。正如我的MATLAB原型中所发生的那样。从分析器报告中,我感觉到每个Halide::sum都两次重复计算dw项:

blf:                   6.999ms   (0%)    threads: 17.857 peak: 3396648  num: 1         avg: 3396648
blf_sum_02:            373.914ms (35%)   threads: 23.247 stack: 32
blf_sum_01:            376.112ms (35%)   threads: 23.376 stack: 32

在此之前,我手动打开了循环,然后Halide简化了重复计算。

现在我不能做同样的事情,因为我也不知道:

  1. 如何手动编写for loop,这取决于传输到生成器的参数。
  2. 如何将dw转换为Func。既然我有 “错误:在Func“ dw”的纯定义中:在纯函数定义中引用的归约域。”

我将很高兴为您提供帮助。

P.S。

我试图将dw表达式重写为4维Func + compute_root()。但这仅适用于较小的过滤器尺寸。因为对于大型过滤器,我会收到错误消息:

Total size for allocation dw is constant but exceeds 2^31 - 1.

Total allocation for buffer dw is 2501065144, which exceeds the maximum size of 2147483647

0 个答案:

没有答案