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

Invalid uniqueness simplification on trivial program #1271

Closed
athas opened this issue Mar 15, 2021 · 6 comments
Closed

Invalid uniqueness simplification on trivial program #1271

athas opened this issue Mar 15, 2021 · 6 comments

Comments

@athas
Copy link
Member

athas commented Mar 15, 2021

Somewhat surprisingly, the compiler messes this up:

let main (xs: *[]i32) =
  let xs' = zip xs xs
  let xs'[0] = (0,0)
  in xs'
@athas
Copy link
Member Author

athas commented Mar 15, 2021

I'm not even sure this should be type correct.

@athas
Copy link
Member Author

athas commented Mar 15, 2021

The program should work, but we need to stop pretending the intrinsic zip doesn't need to copy its input - it does. (Although in many cases this copy can be simplified away later.) I just need to figure out whether the problem is rooted in this intrinsic, or whether it can be provoked without using any dubiously typed intrinsics.

@athas
Copy link
Member Author

athas commented Mar 15, 2021

The root of the problem is this: our implementation strategy for zip has been to turn it into a no-op, because we always keep arrays of pairs "unzipped" in the core IR. This is generally fine, but it is not with respect to uniqueness, because consuming the result of zip xs xs does not just "consume xs once", it consumes it twice (if there is an aliasing relationship). Hence this aliasing relationship should not exist, and when I'm done fixing this, it won't. We have decent copy-elimination optimisations in the simplifier, so hopefully this will not have negative performance impact (but if it does, tough luck, correctness is more important).

@melsman
Copy link
Contributor

melsman commented Mar 16, 2021 via email

@melsman
Copy link
Contributor

melsman commented Mar 16, 2021 via email

@athas
Copy link
Member Author

athas commented Mar 16, 2021

No, because uniqueness in Futhark isn't really uniqueness. If you have a function f : a -> a, then even though the value produced by f x is not unique, you can still consume it, if you can consume x (because there is an aliasing relationship). This was added precisely so we didn't need unique/nonunique variants of functions like transpose and zip. The alternative would be a significant complication of the type system to add "uniqueness polymorphism". In programming languages with linear types, this often takes the form of "multiplicity polymorphism", which can get quite complicated (see Linear Haskell).

In Futhark, uniqueness only matters across function calls (so in function types essentially), and plays two roles:

  • Inside a function, you can consume parameters that are marked as unique.
  • A unique return value of a function will not alias any of the function arguments.

(There's a few more rules; e.g. inside a function you cannot consume anything that is free in the function.)

philass pushed a commit that referenced this issue Apr 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants