Проблемы с оператором выбора Halide

Я пытаюсь сделать некоторые вычисления трафарета, используя Halide. Итак, предполагая базовый 5-точечный 2D-трафарет, для оценки некоторого значения в ячейке i,j мне нужны значения i-1,j i-2,j, i+1,j i+2,j. Теперь то, как это работает в C++, заключается в том, что у меня есть оператор for:

for(int i = 2; i < max_i - 2; i++)
for(int j = 2; j < max_j - 2; j++)
Calculate out = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j))

Теперь я пытаюсь сделать то же самое с Halide. поэтому у меня есть вызванный буфер, который имеет то же значение, что и мой входной массив в коде C++. И у меня Func окликнул:

out(i,j) = select(i >= 2 && j >= 2, some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)) ,0.0f)

Когда я запускаю этот код, я получаю следующую ошибку:

Ошибка: Доступ к входному буферу b0 осуществляется с -1, что предшествует минимуму (0) в измерении 0. Прервано (дамп ядра)

Насколько я понимаю, причина этой ошибки заключается в том, что оператор select оценивает оба оператора, поэтому, хотя я не хочу ничего вычислять для значений i и j меньше двух, функция оценивается при i = 0 и j = 0 и, следовательно, неверный адрес доступа.

Так можно ли это сделать в Halide? Существуют ли какие-либо другие эквиваленты для операторов if/else?


person B.Md    schedule 03.10.2016    source источник


Ответы (1)


Использование граничного условия сделает то, что вы хотите: Func unbounded; unbounded(i, j,) = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)); out(i, j) = BoundaryConditions::constant_exterior(unbounded, 0.0f, 2, width - 4, 2, height - 4)(i, j);

Я считаю, что вы можете использовать «Expr ()» вместо «ширина - 4» или «высота - 4», если вы хотите, чтобы максимум был неограничен.

Использование функций if BoundaryConditions позволяет намекнуть компилятору, какое направление конструкции if/else более вероятно.

person Zalman Stern    schedule 03.10.2016