archives

Alien worlds, values, and you can't touch this

Conventional programs operate on values from one coherent "world;" e.g., many programs execute on a Von Neumann machine (i.e., the CPU world) where values are stored in registers or in uniform access memory while GPU-based programs operate in a very different world with severe computational and memory restrictions. Other examples of these worlds include distributed and parallel computing environments (futures, map reduce clusters), persistent data stores (relational and graph databases), worlds where time is abstracted (FRP), worlds where space is abstracted (GPU, various databases, array programming languages), and so on.

Typically, our bridge between different worlds is a very coarse API where code on the other side is often written in a different language, but DSLs/libraries like Bling can allow us to manipulate from the CPU world resources and values from other worlds through various wrapping and indirection tricks. So in Bling we can manipulate a timeless FRP-world where signal-like values are composed and routed between UI components, or we can write some C# code that operates on GPU-based values to express vertex layout and pixel colors.

Such techniques are hardly transparent: we must firewall values between different worlds as they either do not mix or how they mix is very tricky and possibly very expensive. An int on the GPU is very different from an int on the CPU even if they both support "+;" given a + b, where a is a GPU values and is a CPU value, the result is a GPU value and we must add extra logic to route b onto the GPU at runtime (as a global shader parameter). We could even bring the GPU int back to the CPU somehow, but only at extreme cost that involves transferring GPU memory to CPU memory; its not something that should be allowed to be done lightly.

Haskell seems to have great support for world bridging, possibly because its own world is so idealized that bridging is easier as well as often necessary. My question, and idea, is would it make sense to add specific support in a programming language for world bridging; i.e., should a language have specific support for alien values that do not come from its own native world? Alien values will often share data types with the host world; e.g., a CPU int vs. an alien int, and many operations on those data types will often have some kind of reasonable interpretation (e.g., gpu_a + 1 yields a gpu value that is formed from an add computation). What sort of abstractions would be necessary to allow for as many safe compositions, preventing unsafe compositions, and making expensive operations very obvious?