Предположим, у меня есть входная функция, которая выдает 3-кортежа на каждый пиксель: первый канал имеет оттенки серого, второй и третий каналы используются как относительные смещения. Я хочу, чтобы Func
переместил пиксель по смещению, т.е.
output(x + input(x, y)[1], y + input(x, y)[2]) = input(x, y)[0];
. Это работает, но кажется крайне неэффективным и громоздким:
Func move(Expr width, Expr height, Func input)
{
Func move { "move" };
Var x { "x", "y" };
move(x, y) = input(x, y)[0];
RDom r { 0, width, 0, height, 0, width, 0, height };
r.where(input(r.x, r.y)[1] > 0 || input(r.x, r.y)[2] > 0);
r.where(r.z == r.x + input(r.x, r.y)[1]);
r.where(r.w == r.y + input(r.x, r.y)[2]);
move(r.z, r.w) = input(r.x, r.y)[0];
return move;
}
Насколько я понимаю, 4D RDom
будет l oop во всем диапазоне, но оценивает только два внутренних цикла r.z
и r.w
в точном целевом пикселе. Я хотел бы полностью пропустить циклы, например:
Func move(Expr width, Expr height, Func input)
{
Func move { "move" };
Var x { "x", "y" };
move(x, y) = input(x, y)[0];
RDom r { 0, width, 0, height };
r.where(input(r.x, r.y)[1] > 0 || input(r.x, r.y)[2] > 0);
move(r.x + input(r.x, r.y)[1], r.y + input(r.x, r.y)[2]) = input(r.x, r.y)[0];
return move;
}
Это не работает, к сожалению, ни какие-либо варианты этого - я не понимаю, почему?
В качестве обходного пути Я пытался сделать границы меньше (границы смещений известны и малы), но также безуспешно:
template <int MAX_DISP = 10>
Func move(Expr width, Expr height, Func input)
{
Func move { "move" };
Var x { "x", "y" };
move(x, y) = input(x, y)[0];
RDom r { 0, width, 0, height, 0, MAX_DISP, 0, MAX_DISP };
r.where(input(r.x, r.y)[1] > 0 || input(r.x, r.y)[2] > 0);
r.where(r.z == input(r.x, r.y)[1]);
r.where(r.w == input(r.x, r.y)[2]);
move(r.x + r.z, r.y + r.w) = input(r.x, r.y)[0];
return move;
}
Разве это не должно сработать? Кажется, арифметика c в индексе Expr
s с RDom Var
s в них строго ограничена - но ошибки нет, просто она не работает. Может кто-нибудь уточнить, что возможно в RDom
функциях, а что нет?