Skip to content

ENH: _lib: add common machinery for low-level callback functions#6509

Merged
rgommers merged 32 commits into
scipy:masterfrom
pv:ccallbacks
Jan 4, 2017
Merged

ENH: _lib: add common machinery for low-level callback functions#6509
rgommers merged 32 commits into
scipy:masterfrom
pv:ccallbacks

Conversation

@pv

@pv pv commented Aug 22, 2016

Copy link
Copy Markdown
Member

Replace the various approaches to combined Python and low-level compiled callback functions (e.g. in integrate.quad, ndimage, ...) with something better.

We need this part of a FFI layer in Scipy, because the FFI solutions in Python are not standard, and we want to interoperate with all of them. Moreover, FFI is not standard even across Scipy, and we want a reusable solution.
Supported are:

  • pure-python callbacks
  • cython "api" exported C functions
  • ctypes function pointers
  • pycapsule'd function pointers
  • cffi function pointers.

Caller/thunk code can be implemented in C or Cython.

I ended up with a design where the callback functions need to be explicitly wrapped by the user in LowLevelCallable object. This is because parsing e.g. ctypes callback signatures can take a few µs, so users may want to "precompile" them. Another reason is that if sometime in the future, PyPy becomes more important and Scipy switches to cffi etc, changing the design probably is easier.

The specific use cases in integrate.quad and ndimage still handle also the current "legacy" formats, to preserve backward compat.

Fixes gh-4831, gh-5002

  • test reentrancy/threadsafety rigorously
  • write cython .pxd wrapper for ccallback.h
  • decide if the (module, "name") cython syntax makes sense
  • decide if the (func, user_data) syntax makes sense
  • convert ndimage callbacks
  • maybe move everything from _ccallback.c to Cython? --- no need to do that in the end, leave some test code in C as a coding example

@pv pv mentioned this pull request Aug 22, 2016
2 tasks
@pv pv added the needs-work Items that are pending response from the author label Aug 22, 2016
@pv pv force-pushed the ccallbacks branch 4 times, most recently from 9d2f016 to a80c801 Compare August 24, 2016 21:01
@pv pv removed the needs-work Items that are pending response from the author label Sep 3, 2016
@pv pv changed the title WIP: ENH: _lib: add common machinery for low-level callback functions ENH: _lib: add common machinery for low-level callback functions Sep 3, 2016
@pv

pv commented Sep 3, 2016

Copy link
Copy Markdown
Member Author

I think this is more or less ready, comments welcome.
More controversial point may be where to put LowLevelCallable --- I put it in the top level namespace.

@pv pv added enhancement A new feature or improvement maintenance Items related to regular maintenance tasks labels Sep 3, 2016
@nmayorov

nmayorov commented Sep 6, 2016

Copy link
Copy Markdown
Contributor

It looks like a really great work.

I wonder if it would be possible to make an extended tutorial for LowLevelCallable where usage of each option from ctypes, cffi, Cython, or contained in PythonPyCapsuleobjects. will be shown on a single problem? It will be helpful for people who not well familiar with Python-C interaction (like myself).

@rgommers

Copy link
Copy Markdown
Member

More controversial point may be where to put LowLevelCallable --- I put it in the top level namespace.

We never put anything there, but in this case I think I agree - there's no other obvious place.

@rgommers

Copy link
Copy Markdown
Member

I wonder if it would be possible to make an extended tutorial

@nmayorov the last commit adds documentation which looks quite nice to me. See https://926-1460385-gh.circle-artifacts.com/0//home/ubuntu/scipy/doc/build/html-scipyorg/ccallback.html

@rgommers

Copy link
Copy Markdown
Member

Looks impressive @pv. Reviewing this PR is nontrivial - it's massive and pretty low-level. I'm tempted to just start using it and see if anything unexpected happens. Starting at the top of the diff somehow doesn't make too much sense to me. And I'll ping the people on gh-4831 who were interested.

@pv

pv commented Sep 19, 2016

Copy link
Copy Markdown
Member Author

For reviewing, I would suggest starting by looking at:
.

  1. The new C code in __quadpack.h, compared to the old.
  2. The changes in C code in nd_image.c
  3. The contents of ccallback.h
  4. The suggested usage in the examples e.g. tutorial
  5. Think about whether the LowLevelCallable should be put inside quad()
    so that you could just pass in cffi/ctypes callables. But I think the
    current way is a good approach, because it solves the problem of how to
    pass in the void* pointer to additional data without having to add new
    keyword arguments to functions.
    .
    The rest of the code is mostly for testing the feature.
    .
    As I see it, the alternative to this would be converting our wrapper
    codes to cffi --- it appears to me to be the best of the FFI options for
    this purpose. However, I don't see how it could work together with Cython.

-------------------------------------------
user_data = ctypes.c_double(shift)
ptr = ctypes.cast(ctypes.pointer(user_data), ctypes.c_void_p)
callback = LowLevelCallable.from_cython(example, "transform", ptr)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this example also require adding a .pxd file to export the C api?

@person142

Copy link
Copy Markdown
Member

Would it make sense to collect the examples into a single new tutorial page? Once this is in I imagine use of it is going to proliferate (seems like it's already in the works for ODE solvers), and it might save replication to have an authoritative guide to point to.

@pv

pv commented Sep 19, 2016 via email

Copy link
Copy Markdown
Member Author

@pv

pv commented Sep 19, 2016 via email

Copy link
Copy Markdown
Member Author

@person142

Copy link
Copy Markdown
Member

No, I think "cdef api" does the same magic.

So it does. That's a good trick to know about.

@dhirschfeld

dhirschfeld commented Sep 20, 2016

Copy link
Copy Markdown

I tried building the branch but with no luck :( First I had to downgrade setuptools because of incorrect path quoting (IIUC) after which it got a lot further but finally failed with the below errors:

building 'scipy.ndimage._nd_image' extension
compiling C sources
creating build\temp.win-amd64-3.5\Release\scipy\ndimage
creating build\temp.win-amd64-3.5\Release\scipy\ndimage\src
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iscipy\ndimage\src -IC:\bin\Anaconda3\lib\site-packages\numpy\core\include -Iscipy\_lib\src -IC:\bin\Anaconda3\lib\site-packages\numpy\core\include -IC:\bin\Anaconda3\include -IC:\bin\Anaconda3\include -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include\intel64" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mpi\intel64\bin\..\..\intel64\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mkl\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\tbb\bin\..\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include\intel64" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mpi\intel64\bin\..\..\intel64\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mkl\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\tbb\bin\..\include" /Tcscipy\ndimage\src\nd_image.c /Fobuild\temp.win-amd64-3.5\Release\scipy\ndimage\src\nd_image.obj
nd_image.c
c:\bin\anaconda3\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(12) : Warning Msg: Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
C:\bin\Anaconda3\lib\site-packages\numpy\core\include\numpy/npy_3kcompat.h(179): warning C4244: '=': conversion from 'Py_ssize_t' to 'int', possible loss of data
scipy\_lib\src\ccallback.h(133): error C2061: syntax error: identifier 'jmp_buf'
scipy\_lib\src\ccallback.h(140): error C2059: syntax error: '}'
scipy\_lib\src\ccallback.h(260): warning C4133: 'function': incompatible types - from 'PyTypeObject *' to 'PyObject *'
scipy\_lib\src\ccallback.h(275): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(276): error C2037: left of 'c_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(277): error C2037: left of 'user_data' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(278): error C2037: left of 'signature_index' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(284): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(285): error C2037: left of 'c_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(286): error C2037: left of 'user_data' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(287): error C2037: left of 'signature_index' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(307): error C2037: left of 'signature_index' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(308): error C2037: left of 'signature_index' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(325): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(326): error C2037: left of 'c_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(327): error C2037: left of 'user_data' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(335): error C2037: left of 'prev_callback' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(339): error C2037: left of 'prev_callback' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(354): error C2037: left of 'prev_callback' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(355): error C2037: left of 'prev_callback' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(355): error C2198: 'ccallback__set_thread_local': too few arguments for call
scipy\_lib\src\ccallback.h(357): error C2037: left of 'prev_callback' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(358): error C2037: left of 'c_function' specifies undefined struct/union 'ccallback'
scipy\_lib\src\ccallback.h(359): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(284): error C2037: left of 'info_p' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(296): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(296): error C2198: 'PyObject_Call': too few arguments for call
scipy\ndimage\src\nd_image.c(320): error C2079: 'callback' uses undefined struct 'ccallback'
scipy\ndimage\src\nd_image.c(327): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(328): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(360): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
scipy\ndimage\src\nd_image.c(365): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(368): error C2224: left of '.info_p' must have struct/union type
scipy\ndimage\src\nd_image.c(373): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(374): error C2224: left of '.user_data' must have struct/union type
scipy\ndimage\src\nd_image.c(382): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(382): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(383): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
scipy\ndimage\src\nd_image.c(396): error C2037: left of 'info_p' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(407): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(407): error C2198: 'PyObject_Call': too few arguments for call
scipy\ndimage\src\nd_image.c(428): error C2079: 'callback' uses undefined struct 'ccallback'
scipy\ndimage\src\nd_image.c(435): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(436): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(468): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
scipy\ndimage\src\nd_image.c(473): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(476): error C2224: left of '.info_p' must have struct/union type
scipy\ndimage\src\nd_image.c(481): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(482): error C2224: left of '.user_data' must have struct/union type
scipy\ndimage\src\nd_image.c(489): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(489): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(490): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
scipy\ndimage\src\nd_image.c(572): error C2037: left of 'info_p' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(588): error C2037: left of 'py_function' specifies undefined struct/union 'ccallback'
scipy\ndimage\src\nd_image.c(588): error C2198: 'PyObject_Call': too few arguments for call
scipy\ndimage\src\nd_image.c(614): error C2079: 'callback' uses undefined struct 'ccallback'
scipy\ndimage\src\nd_image.c(621): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(622): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(658): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
scipy\ndimage\src\nd_image.c(663): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(666): error C2224: left of '.info_p' must have struct/union type
scipy\ndimage\src\nd_image.c(671): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(672): error C2224: left of '.user_data' must have struct/union type
scipy\ndimage\src\nd_image.c(682): error C2224: left of '.py_function' must have struct/union type
scipy\ndimage\src\nd_image.c(682): error C2224: left of '.c_function' must have struct/union type
scipy\ndimage\src\nd_image.c(683): warning C4133: 'function': incompatible types - from 'int *' to 'ccallback_t *'
error: Command "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iscipy\ndimage\src -IC:\bin\Anaconda3\lib\site-packages\numpy\core\include -Iscipy\_lib\src -IC:\bin\Anaconda3\lib\site-packages\numpy\core\include -IC:\bin\Anaconda3\include -IC:\bin\Anaconda3\include -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include\intel64" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mpi\intel64\bin\..\..\intel64\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mkl\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\tbb\bin\..\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\\winrt" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\include\intel64" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mpi\intel64\bin\..\..\intel64\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mkl\include" -I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\tbb\bin\..\include" /Tcscipy\ndimage\src\nd_image.c /Fobuild\temp.win-amd64-3.5\Release\scipy\ndimage\src\nd_image.obj" failed with exit status 2

NB: I quite possibly wasn't doing something right but thought I'd post the error in case it points to an actual problem with the windows build
NBB: This was with the latest Intel parallel studio 2017

@pv

pv commented Oct 13, 2016

Copy link
Copy Markdown
Member Author

@dhirschfeld: may be just missing #include <setjmp.h>, added in 56f0925

@dhirschfeld

Copy link
Copy Markdown

Thanks @pv - that fixed the compilation so I can now test this branch on py35/win64.

I'm very interested in this branch as I have an expensive integral which I'm hoping to speedup using the numba cfunc functionality. I haven't been able to make full use of it so far because quad hasn't allowed passing in extra parameters correctly when using the ctypes interface (IIUC).

In [4]: from scipy.integrate import quad

In [5]: def f1(x, mu):
   ...:     return np.exp(-x**2)/(1+np.exp(-(x-mu)))

In [6]: quad(f1, -np.inf, np.inf, args=(1.1,))
Out[6]: (0.47866266846942096, 5.656862062202448e-09)

In [7]: quad(f1, -np.inf, np.inf, args=(1.9,))
Out[7]: (0.26575640518956256, 2.7307507646266408e-09)

I implemented this using numbas cfunc as follows:

In [58]: from numba import types
    ...: from numba import carray, cfunc, float64
    ...: from scipy import LowLevelCallable

In [59]: @cfunc(float64(float64, types.voidptr))
    ...: def f2(x, ptr_mu):
    ...:     mu = carray(ptr_mu, (1,), dtype=float64)[0]
    ...:     return np.exp(-x**2)/(1+np.exp(-(x-mu)))

In [60]: mu = ctypes.c_double(1.1)
    ...: mu_ptr = ctypes.cast(ctypes.pointer(mu), ctypes.c_void_p)
    ...: f = LowLevelCallable(f2.ctypes, mu_ptr)

In [61]: quad(f, -np.inf, np.inf)
Out[61]: (0.47866266846942096, 5.656862062202448e-09)

In [62]: mu = ctypes.c_double(1.9)
    ...: mu_ptr = ctypes.cast(ctypes.pointer(mu), ctypes.c_void_p)
    ...: f = LowLevelCallable(f2.ctypes, mu_ptr)

In [63]: quad(f, -np.inf, np.inf)
Out[63]: (0.26575640518956256, 2.7307507646266408e-09)

...with a resulting 16x speedup!

In [73]: %timeit quad(f, -np.inf, np.inf)
10000 loops, best of 3: 53.4 µs per loop

In [74]: %timeit quad(f1, -np.inf, np.inf, args=(1.9,))
1000 loops, best of 3: 859 µs per loop

In [75]: quad(f1, -np.inf, np.inf, args=(1.9,))[0] == quad(f, -np.inf, np.inf)[0]
Out[75]: True

🎉

@dhirschfeld

Copy link
Copy Markdown

...since it's slightly non-trivial it might make for a good example - but that's possibly beter located in the numba docs?

cc: @pitrou

pv added 2 commits December 18, 2016 22:52
…r than index

Since several signatures can be equivalent, it's more convenient to
refer to them by user-specified codes, rather than by their index in the
list of signatures.
@rgommers rgommers added this to the 0.19.0 milestone Jan 3, 2017
@pv

pv commented Jan 4, 2017 via email

Copy link
Copy Markdown
Member Author

@rgommers

rgommers commented Jan 4, 2017

Copy link
Copy Markdown
Member

Okay, thanks for confirming.

@rgommers

rgommers commented Jan 4, 2017

Copy link
Copy Markdown
Member

Let's get this in then - has been thoroughly reviewed, seems to be in good shape, and would be good to have it in master for a few weeks before branching 0.19.x.

@rgommers

rgommers commented Jan 4, 2017

Copy link
Copy Markdown
Member

Or do you still want to do anything about this comment regarding numba ints:#4933 ?

@pv

pv commented Jan 4, 2017 via email

Copy link
Copy Markdown
Member Author

@rgommers rgommers merged commit cc9f6b2 into scipy:master Jan 4, 2017
@rgommers

rgommers commented Jan 4, 2017

Copy link
Copy Markdown
Member

Okay in it goes. Thanks Pauli! And thanks everyone for the reviews!

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

Labels

enhancement A new feature or improvement maintenance Items related to regular maintenance tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants