Галоидная редукция по двумерной границе домена

В фильтре, который я реализую, есть шаг, делающий некоторое уменьшение границы квадратной области

RDom r(0, filter_size, 0, filter_size);
r.where( (r.x == 0 || r.x == filter_size - 1) 
       || (r.y == 0 || r.y == filter_size - 1));

Однако это делает обход домена O(filter_size^2) в то время как полезное сокращение домена только O(filter_size), Теперь моя операция сокращения немного сложна, поэтому повторяюсь, если для каждой стороны окна фильтра возникает беспорядок. Есть ли элегантный и эффективный способ сделать это в Halide?

2 ответа

Решение

Код, который я в конечном итоге использую, не очень элегантен и не очень эффективен, так что приветствуются материалы...

RDom rl(0, filter_size, 0, 2, 0, 2);
Expr rlx = rl.y*rl.x + rl.z*(1 - rl.y)*filter_size;
Expr rly = (1 - rl.y)*rl.x + rl.z*rl.y*filter_size;
Expr x_on_rl = x + rlx - (filter_size+1)/2;
Expr y_on_rl = y + rly - (filter_size+1)/2;

и использование как

range_min(x, y) = Halide::minimum(range_clamped(x_on_rl, y_on_rl));

Я не проверял это, но общая идея состоит в том, чтобы использовать только одно измерение RDom за раз по мере необходимости, чтобы вам не приходилось перебирать внутренности.

RDom r(0, filter_size, 1, filter_size-1);// the y part is different because we don't want to double count the corners
output(x,y,c) = 
Binary_Reduction(Halide::<desired_reduction>(clamped_input(x + r.x, y, c)), 
Binary_Reduction(Halide::<desired_reduction>(clamped_input(x + r.x, y + filter_size -1, c)), 
Binary_Reduction(Halide::<desired_reduction>(clamped_input(x, y + r.y, c)),
                 Halide::<desired_reduction>(clamped_input(x + filter_size - 1, y + r.y, c)))));

Двоичное сокращение - это замена для сокращения пары выражений, таких как Halide::min или просто любой двоичной операции.

является заменой для чего-то вроде Halide::imum или Halide::sum.

Должен дважды проверить скобки.

Другие вопросы по тегам