Q:

Individual dask array boundaries with ghosting

I'm playing with Dask trying to set up a few simple PDE solves using finite differences and I'm wondering if there's a way to specify boundary conditions per-boundary.  
Docs here
The current ghost.ghost function allows specifying a few different B.C.s but they're always the same for both y-boundaries and both x-boundaries.  
Docs mention that I can pad out a boundary arbitrarily, which I'm happy to do, but is there then a way to tell ghost.ghost to not add any boundaries on the outside of the chunks?

A:

ghost_internal
It appears that at the moment there isn't a way to do this from the user-facing ghost or map_overlap functions.  However, you can use the dask.array.ghost.ghost_internal function to accomplish internal ghosting without specifying external boundaries (this is the main function used by ghost).  
In [1]: import dask.array as da

In [2]: x = da.arange(10, chunks=5)

In [3]: x.chunks
Out[3]: ((5, 5),)

In [4]: y = da.ghost.ghost_internal(x, {0: 2})

In [5]: y.chunks
Out[5]: ((7, 7),)

In [6]: y.compute()
Out[6]: array([0, 1, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 8, 9])

You may want to do this, then call map_blocks on the larger blocks and then call dask.array.ghost.trim_internal to trim away the excess overlap with the same axis depth.
But more generally this should be accessible from the more convenient ghost and map_overlap functions.  Can I ask you to raise an issue?
Finite Differences
More generally to the application of finite differences.  Dask.arrays are somewhat limited here because they refuse to mutate existing data.  This results in many copies which run a bit slower than a simple finite differencing scheme.  The cost of copying would be less painful for more costly computations.  Here is a quick notebook that demonstrates this slowdown.  Since creating that notebook the copying overhead has been reduced by a factor of two, but is still significant.

