Repository navigation
Conversation
59ef4ea to
7ab13be
Compare
|
Rebased off PR #11175. We have loops in |
|
Setup looks great; the trick will indeed be to have a nice way to choose BLAS etc for the inner loop. |
|
Since |
|
@mattip - I think the gufunc loops need some special-case speed-ups that the ufuncs already have, in particular for the case that there is no outer looping to be done, in which case the elementary function should just be called directly. But that is independent of One thing to possibly consider for |
|
One of the trickier parts of this is what to do for non-contiguous memory. Just changing the benchmark code from |
|
Indeed, I think that when the strides are not contiguous, one probably should copy data over, but there is a question for what number of points this becomes useful. My guess would be that for small arrays the copy is so fast that it might not matter. Aside: I've been implementing this in astropy - this includes a very basic 3x3 matrix multiplication routine, and in my implementation I check in the inner loop whether copies are necessary [1]. As I wrote above, I think it would be more elegant to do this outside, and select a copying or non-copying loop -- and pass on some temporary storage to the inner loop if needed -- though it may not matter that much speed-wise. Also, I think almost anything will be faster than the current call to |
|
I like the last commit - but isn't that independent of |
7700bf9 to
7efa656
Compare
|
it seems the matmul vector-vector case for column-row -> 2d array was not tested. I put a marker in each case of all the matmul loops, and that one came up missing. |
|
note this is a wip, builds on top of master and pr #11175. Once that is merged I will clean up this branch |
5cf6b60 to
2bcf710
Compare
|
level 1 |
Codecov Report
@@ Coverage Diff @@
## master #11133 +/- ##
==========================================
+ Coverage 85.7% 85.73% +0.02%
==========================================
Files 327 327
Lines 81995 82139 +144
==========================================
+ Hits 70274 70418 +144
Misses 11721 11721
Continue to review full report at Codecov.
|
tylerjereddy
left a comment
There was a problem hiding this comment.
Please rebase on top of the latest master branch so that `.codecov.yml' setting disabling auto-comments can be detected in the PR.
Thanks for taking these into account. :) We got |
| * out[n, 2] = in1[n, 0]*in2[n, 1] - in1[n, 1]*in2[n, 0] | ||
| */ | ||
| static void | ||
| @TYPE@_cross1d(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func)) |
There was a problem hiding this comment.
I may as well just ask--do we have some docs that describe the mechanics of the @ symbol usage in NumPy C source? It appears to be some kind of mechanism for generalization / substitution, but unless I missed a chapter in the C text book, not standard?
There was a problem hiding this comment.
Numpy uses a custom templating system. The parser is defined in conv_template.py.
There was a problem hiding this comment.
Yup, I know that now, but it is not well exposed documentation -- I've been working on #11689 & to be fair the distutils docs template section is nothing more than a placeholder.
| else | ||
| #endif | ||
| { | ||
| @type@ sum = (@type@)0; /* could make this double */ |
There was a problem hiding this comment.
The comment here means that there's no compelling advantage to having @type@ of sum be flexible, or something else?
| elementary function's implementation. | ||
| #. White spaces are ignored. | ||
| #. An integer as a dimension name freezes that dimension to the value, | ||
| #. The name can be suffixed with a question mark, this make the dimension a |
| (void*)op, dm, dn); | ||
| } else { | ||
| /* cannot reach here */ | ||
| /* printf("inconceivable to reach this line m=%ld, n=%ld, p=%ld\n", |
There was a problem hiding this comment.
remove debug code and raise some kind of exception here?
There was a problem hiding this comment.
We cannot error inside a loop. I could just remove it, but it is helpful for reasoning about the code and can be enabled for debugging
| /* npy_intp ib1_m = is1_m * dm; | ||
| npy_intp ob_m = os_m * dp; */ | ||
| /* | ||
| * TODO: refactor this out to a inner_loop_selector, instead of |
There was a problem hiding this comment.
Still needs to be done?
There was a problem hiding this comment.
Maybe, but not in this iteration of the code
| assert_equal(c, b) | ||
| a = np.arange(18).reshape(2, 3, 3) | ||
| c = np.matmul(a, a, out=a[::-1, ...]) | ||
| assert(c.base is a.base) |
There was a problem hiding this comment.
why the switch from assert_ above to plain assert here?
| assert_raises(ValueError, umt.cross1d, a, np.arange(4.)) | ||
| assert_raises(ValueError, umt.cross1d, a, np.arange(3.), np.zeros((3, 4))) | ||
|
|
||
| def test_can_ignore_signature(self): |
There was a problem hiding this comment.
Any way to split this 70-line "unit test" up into smaller pieces logically?
There was a problem hiding this comment.
Yes, my fault. Might be good to refactor, but out of scope for this PR, I think.
|
Closing this, will reopen as a new, cleaner PR |
The discussion of issue #9028 yielded two different possible directions for allowing
ndarraysubclasses to override__matmul__via__array_ufunc__. This is option 1 - allow a singleufuncmatmulwhich will implement vector-vector, vector-matrix, matrix-vector, and matrix-matrix multiplication. In this PR, which builds onPR #11132PR #11175, the implementation ofmatmulis converted to aufunc.Note the pull request incorporates the changes from pr #11132 so the changesets are repeated
What changed?
matmulis now implemented as a trueufunc, it appears in theumath'sn_ops, can be set and gotten usingPyArray_{G,S}etNumericOps, and its loops are defined inloops.c.srcWhat is not finished?
since I simply copied the partial loop implementation from_umath_tests,matmulcannot accept complex or half-float dtypesI wrote the code together with PR WIP: ENH: Expand gufunc signature to allow flexible dimension specs #11132 I probably have chages there that belong here and visa-versadotto make this fasterWhat is next?
Get feedback on the relative merits of this approach vs. the one taken in PR WIP: ENH: allow __array_ufunc__ to override __matmul__ #11061, where I produced a demi-The choice has been made, this approach wins.ufuncwith a wrapper function that can be used to convert any function into aufunc.Edit: update status