Quansight-Labs / uarray

A general dispatch and override mechanism for Python.
https://uarray.org/
BSD 3-Clause "New" or "Revised" License
101 stars 26 forks source link

What is a simple code example using uarray that demonstrates "replatforming SciPy"? #100

Closed hameerabbasi closed 5 years ago

hameerabbasi commented 5 years ago

Can the simple example be used to illustrate:

hameerabbasi commented 5 years ago

Here's my take on it:

import uarray as ua
import uarray.numpy as np
import uarray.scipy.linalg as spl

# Create array `x` in TensorFlow/PyTorch/Dask/CuPy

a, b, c = spl.svd(x)

# a, b, c is a TensorFlow graph/CuPy array/whatever

with ua.use_graph(True): # Other options are False and None
    # a, b, c are graphs
    a, b, c = spl.svd(x)

# a, b, c are arrays

# Backends

# Can be used as context manager or to set default
with ua.use_backend(ua.backends.PyTorch, coerce=True):
    # Everything here will use PyTorch and coerce all arrays.

with ua.use_backend(ua.backends.PyTorch, ua.backends.NumPy):
   # Attempts to use PyTorch, and failing that, NumPy

with ua.use_backend(ua.backends.PyTorch, ua.backends.NumPy, coerce=ua.backends.PyTorch):
    # When multiple backends are specified, you must specify the one to coerce to on failure of type check.

Can the simple example be used to illustrate:

teoliphant commented 5 years ago
# Create array `x` in TensorFlow/PyTorch/Dask/CuPy

a, b, c = spl.svd(x)

Yes, yes!  This is the fundamental use-case.  All functions return the kind of array they pull in (if they are all the same.  If they aren't all the same, then it raises an error). 

# a, b, c is a TensorFlow graph/CuPy array/whatever

with ua.use_graph(True): # Other options are False and None
    # a, b, c are graphs
    a, b, c = spl.svd(x)

 # I like this. This adds additional value where you can get a graph.  A decorator around a function that  
 # will produce a graph on the return value could also work.

# a, b, c are arrays

# Backends

# Can be used as context manager or to set default
with ua.use_backend(ua.backends.PyTorch, coerce=True):
    # Everything here will use PyTorch and coerce all arrays.

with ua.use_backend(ua.backends.PyTorch, ua.backends.NumPy):
   # Attempts to use PyTorch, and failing that, NumPy

with ua.use_backend(ua.backends.PyTorch, ua.backends.NumPy, coerce=ua.backends.PyTorch):
    # When multiple backends are specified, you must specify the one to coerce to on failure of type check.

 # These are interesting ideas.  I like them.
teoliphant commented 5 years ago

Yes, this is what the API should look like. This is what we need.

ashwinvis commented 5 years ago

@hameerabbasi Thank you for that simple example demonstrating the vision... I believe it is already outdated now that unumpy is a separate package. Some documentation would be nice for outsiders to understand what is working now and what's on the roadmap.

hameerabbasi commented 5 years ago

@ashwinvis For now I have this simple notebook up. I've attempted to get most ufuncs and ufunc-related reductions (sum, prod, any, all, min, max) working so far with Xnd, PyTorch and NumPy.

You can take a look at https://github.com/Quansight-Labs/uarray/blob/master/unumpy/tests/test_numpy.py to see what's supported so far, as far as the user-facing API goes.

As far as the dev-facing API, here's a notebook demonstrating it: https://nbviewer.jupyter.org/github/Quansight-Labs/uarray/blob/master/notebooks/basic_tutorial.ipynb

I do plan to write docs once I have enough of the API implemented.

hameerabbasi commented 5 years ago

Docs are up at https://uarray.readthedocs.io/en/latest/