Search code examples
if-statementselecthalide

Issues with Halide select statement


I'm trying to do some stencil computation using Halide. So assuming a basic 5 point 2D stencil, to evaluate some value at cell i,j I need the values of i-1,j i-2,j, i+1,j i+2,j. Now the way this works in C++ is that I have a for statement:

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))

Now I'm trying to do the same thing with Halide. so I have a Buffer called in which has the same value as my input array in the C++ code. And I have a Func called out:

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)

When I run this code I get the following error:

Error: Input buffer b0 is accessed at -1, which is before the min (0) in dimension 0 Aborted (core dumped)

From my understanding, the reason for this error is that the select statement evaluates both statements so eventhough I don't want to calculate anything for i and j values less than two, the function is evaluated at i = 0 and j = 0 and thus the invalid address access.

So is there anyway to do this in Halide? Are there any other equivalents for if/else statements?


Solution

  • Using a boundary condition will do what you want: 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);

    I believe you can use "Expr()" instead of "width - 4" or "height - 4" if you want the maximum unbounded.

    The use if BoundaryConditions functions allows hinting the compiler which direction of the if/else construct is more likely.