Skip to content

Instantly share code, notes, and snippets.

@mattharrigan
Last active April 28, 2017 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattharrigan/b784b50b451a41f327b3a990ec043557 to your computer and use it in GitHub Desktop.
Save mattharrigan/b784b50b451a41f327b3a990ec043557 to your computer and use it in GitHub Desktop.

This is a wish list of possible enhancements to numpy ufuncs. My goal was to be as comprehensive as possible. Many of the items below are taken from existing issues and other people's suggestions. Some are my own observations after writing a few gufuncs.

  1. Add axis or axes kwarg to gufuncs. This has been discussed several times, most recently here
  2. Allow multiple signatures for a gufunc, basically multiple dispatch. Discussed recently here. This is also a more general solution to optionally allowing broadcasting over core dimensions for certain gufuncs, which I also think is a good idea.
  3. Allow kwargs specific to a ufunc which are not general across a broad class of ufuncs. This would allow many benefits of kwargs such as default arguments. Kwargs are also a significant obstacle to making more NumPy functions ufuncs, should that be desired.
  4. Allow a gufunc to choose the output array size given the function inputs for signatures where the size is not trivial. For example with a signature (),()->(i), the dimension of i is not known. Currently the output array must be provided, but it would nice if the ufunc "just worked".
  5. Allow for a better path to set void* data. Currently it is somewhat difficult to get anything into the data pointer. A function which recieves the inputs and can assign to data before the loop may have benefits
  6. Allow a ufunc to potentially defer computation to a non ufunc, ie a blas routine.
  7. Allow the gufunc to provide hints on optimal inner loop sizes for iteration, ie blocking common to matrix multiplication
  8. For gufuncs, allow the function to operate over portions of the dimension in multiple calls. Currently I think an gufunc with signature (i)->() must be called exactly once for the entire core dimension. ufunc reduce allows that to be broken up into segments, possibly allowing other optimizations, with the identity attribute. A generalized version of ufunc reduce and identity would be nice.
  9. Allow a gufunc to signal an early exit, where no further inner loop or array iteration calls are required. This might be useful for things such as "any" or "all"
  10. Allow a gufunc to trim output array size after finishing the loop. Some functions don't know the output size in advance, such as nonzero for a simple example. It may make sense to preallocate the maximum possible size and trim to the correct size after looping, avoiding the need to scan the array twice.
  11. Add other methods and kwargs from ufuncs to generalized ufuncs. Specifically "at", "where", and "reduceat" seem like there might be useful generalizations for core dimensions.
  12. Add a mechanism to chain ufunc calls for improved performance. "at" and "where" already do a limited form of chaining, basically combining fancy indexing with a ufunc call. It would be nice to have a more general method with wider uses.

Admittedly many of these suggestions may not be appropriate. Again my goal was to error on being too comprehensive.

Many of the above may have the same solution. For example, adding an optional function pointer could potentially be an implementation of 3 through 6 and part of 7. I think that is the main benefit of a comprehensive list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment