Overview#
Spatch is a dispatching tool with a focus on scientific python libraries. It integrates two forms of dispatching into a single backend system:
Type dispatching for the main type used by a library. In the scientific python world, this is often the array object.
Backend selection to offer alternative implementations to users. These may be faster or less precise, but using them should typically not change code behavior drastically.
Spatch is opinionated about these points being two different, but related, use-cases. It thus combines machinery to do both, but keeps the related choices separate for the user (and library/backend authors).
Type dispatching#
Many libraries are written for NumPy, but users may wish to use them with other types, for example because code needs to scale from an experiment to a large scale deployment.
Unfortunately, providing code for a host of such types isn’t easy and the original library authors usually have neither the bandwidth nor expertise to do it. Additionally, such layers would have to be optional components of the library.
spatch
allows for a solution to this dilemma by allowing a third party
to enable library functions to work with alternative types.
It should be noted that spatch is not a generic multiple dispatching
library. It is opinionated about being strictly typed (we can and probably
will support subclasses in the future, though).
It also considers all arguments identically. I.e. if a function takes
two inputs (of the kind we dispatch for), there is no distinction for
their order.
Besides these two things, spatch
is however a typical type dispatching
library.
Type dispatching mostly extends functionality to cover function inputs that it did not cover before. Users may choose to work with a specific type explicitly but in many cases the input types decide the use here.
Backend selection#
The type dispatching functionality extends a library to support new types. Another use-case is to not change which types we work with, but to provide alternative implementations.
For example, we may have a faster algorithm that is parallelized while the old one was not. Or an implementation that dispatches to the GPU but still returns NumPy arrays (as the library always did).
Backend selection modifies behavior rather than extending it. In some cases those modifications may be small (maybe it is really only faster). For the user, backend selection often means that they should explicitly select a preferred backend (e.g. over the default implementation). This could be for example via a context manager:
with backend_opts(prioritize="gpu_backend"):
library.function() # now running on the GPU