Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment is not an associative op and we shouldn't be able to rfactor it #7893

Closed
abadams opened this issue Oct 11, 2023 · 1 comment · Fixed by #7894
Closed

Assignment is not an associative op and we shouldn't be able to rfactor it #7893

abadams opened this issue Oct 11, 2023 · 1 comment · Fixed by #7894
Assignees
Labels

Comments

@abadams
Copy link
Member

abadams commented Oct 11, 2023

Consider the following code:

    Func f("f"), g("g");
    Var x("x"), y("y"), u("u");

    RDom r(0, 10);

    f(x) = x;
    f.compute_root();

    g(x) = 4;
    g(r.x) = 17 * f(r.x) + 8;

    g.update().rfactor(r.x, u).compute_root();

    const int W = 20;
    g.bound(x, 0, W);
    Buffer<int> buf = g.realize({W});

    for (int i = 0; i < W; i++) {
        int correct = i < 10 ? (17 * i + 8) : 4;
        if (buf(i) != correct) {
            printf("buf(%d) = %d instead of %d\n",
                   i, buf(i), correct);
        }
    }

It outputs:

buf(0) = 0 instead of 8
buf(1) = 0 instead of 25
buf(2) = 0 instead of 42
buf(3) = 0 instead of 59
buf(4) = 0 instead of 76
buf(5) = 0 instead of 93
buf(6) = 0 instead of 110
buf(7) = 0 instead of 127
buf(8) = 0 instead of 144
buf(10) = 0 instead of 4
buf(11) = 0 instead of 4
buf(12) = 0 instead of 4
buf(13) = 0 instead of 4
buf(14) = 0 instead of 4
buf(15) = 0 instead of 4
buf(16) = 0 instead of 4
buf(17) = 0 instead of 4
buf(18) = 0 instead of 4
buf(19) = 0 instead of 4

(Note buf(9) is correct).

The failure is because rfactor can create loops that apply the associative op using the identity and expect it to have no effect, but for the assignment op we use zero as the identity, and clobbering something with zero most definitely has an effect. If we had some sentinel value we could use as the identity then we could use select(a == sentinel, b, a) as the associative op, but in general we can't deduce an unused value.

I think we're going to have to disallow rfactoring assignment ops. It doesn't make much sense anyway, because the intermediate Func is only populated along a diagonal, so it's a big waste of memory.

@abadams abadams added the bug label Oct 11, 2023
@abadams
Copy link
Member Author

abadams commented Oct 11, 2023

(This was found while trying to fix #7890)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant