refactor backend support to actually separate functionality

This is a first stab at the backend support. It's kept quite fluid for the
moment because a) realistically only OpenCL and NumPy backends will be
developed for the moment and b) it's not quite clear at what level people
should be expected to use the APIs.