0

Suppose we had the following:

Var idx;
Func out;

out(idx) = select(idx == 0, VAL_1, select(idx == 1, VAL_2, VAL3));

It would be nice to be able to force Halide to use if/then/else constructs for this in the loop body, instead of selects. I was assuming that this is done using the specialize() scheduling command:

out.specialize(idx == 0);
out.specialize(idx == 1);

However, this seems to be forbidden:

"Error at (...): Specialization condition (...) depends on Var or RVar idx. 
Specialization conditions may not depend on any Vars or RVars.

Is there a particular reason why this limitation exists? Or maybe some other way to reach the intended behavior, other than unrolling?

Thanks and kind regards,

Sander

Sander Vocke
  • 125
  • 5

2 Answers2

2

Specialization puts an if statement outside of the outermost loop, which means that other Funcs that are compute_at the Func being specialized get included in the specialization.

The only way to get an if statement with a condition that depends on a loop variable is RDom::where, and there's no way to give it an else clause, so this may not be possible. Could you explain more why an if statement is better than unrolling in your case? Is idx parallel?

Andrew Adams
  • 1,396
  • 7
  • 3
  • I didn't realize the if statement would appear outside the outer loop. That clarifies why what i wanted was not possible. In the example I gave, unrolling would be fine. But generally speaking, it means you cannot have an if statement to handle a single case, and select statements for all others - you would always have to unroll completely. On the other hand, I have not found a case so far where that is required. – Sander Vocke Mar 03 '17 at 08:47
1

I would unroll(idx). The select will then be using constants for the conditional and will be optimized out by Halide.

Khouri Giordano
  • 796
  • 3
  • 9