halide / Halide

a language for fast, portable data-parallel computation
https://halide-lang.org
Other
5.78k stars 1.07k forks source link

CheckUnsafePromises inserts checks which get lifted out of `select()`, invalidating what it actually checks. #8302

Closed mcourteaux closed 1 week ago

mcourteaux commented 1 week ago

As a follow-up to #8301, I started using unsafe_promise_clamped to circumvent the bounds-inference issue. Just to double check what I was doing, I enabled check_unsafe_promises, which caused my promises to be checked outside the select() which should represent an if-then-else.

So conceptually, what I'm talking about is this:

    Buffer<float, 3> bufA({10, 10, 25}, "bufA");
    Buffer<float, 3> bufB({10, 10, 25}, "bufB");
    Buffer<float, 2> bufC({10, 10}, "bufC");
    Var x("x"), y("y"), i("i");

    Func concat("concat");
    concat(x, y, i) = select(
        i < 25, bufA(x, y, unsafe_promise_clamped(i, 0, 24)),
        i < 50, bufB(x, y, unsafe_promise_clamped(i - 25, 0, 24)),
                bufC(x, y));

Doesn't work with check_unsafe_promises as both checks end up being next to the select() statement, instead of being inside it.

abadams commented 1 week ago

Again, this is because select evaluates both sides, so your unsafe_promise_clamped calls don't actually hold

abadams commented 1 week ago

If you want an if statement, the only current way to get one is RDom::where

mcourteaux commented 1 week ago

So if I understand well, this unsafe_promise_clamped is actually really unsafe because it behaves like a blend rather than an if-then-else?

abadams commented 1 week ago

That's right.

mcourteaux commented 1 week ago

Okay, thanks. RTFM indeed. :stuck_out_tongue: