Skip to content

Commit b94546d

Browse files
committed
BUG: fix inner() by copying if needed to enforce contiguity
1 parent 626eb37 commit b94546d

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

numpy/core/src/multiarray/cblasfuncs.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,8 @@ cblas_matrixproduct(int typenum, PyArrayObject *ap1, PyArrayObject *ap2,
674674
*
675675
* This is for use by PyArray_InnerProduct. It is assumed on entry that the
676676
* arrays ap1 and ap2 have a common data type given by typenum that is
677-
* float, double, cfloat, or cdouble and have dimension <= 2, and have the
678-
* contiguous flag set. The * __numpy_ufunc__ nonsense is also assumed to
677+
* float, double, cfloat, or cdouble and have dimension <= 2.
678+
* The * __numpy_ufunc__ nonsense is also assumed to
679679
* have been taken care of.
680680
*/
681681

@@ -689,6 +689,24 @@ cblas_innerproduct(int typenum, PyArrayObject *ap1, PyArrayObject *ap2)
689689
npy_intp dimensions[NPY_MAXDIMS];
690690
PyTypeObject *subtype;
691691

692+
/* assure contiguous arrays */
693+
if (!PyArray_IS_C_CONTIGUOUS(ap1)) {
694+
PyObject *op1 = PyArray_NewCopy(ap1, NPY_CORDER);
695+
Py_DECREF(ap1);
696+
ap1 = (PyArrayObject *)op1;
697+
if (ap1 == NULL) {
698+
goto fail;
699+
}
700+
}
701+
if (!PyArray_IS_C_CONTIGUOUS(ap2)) {
702+
PyObject *op2 = PyArray_NewCopy(ap2, NPY_CORDER);
703+
Py_DECREF(ap2);
704+
ap2 = (PyArrayObject *)op2;
705+
if (ap2 == NULL) {
706+
goto fail;
707+
}
708+
}
709+
692710
if (PyArray_NDIM(ap1) == 0 || PyArray_NDIM(ap2) == 0) {
693711
/* One of ap1 or ap2 is a scalar */
694712
if (PyArray_NDIM(ap1) == 0) {

numpy/core/tests/test_multiarray.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4728,6 +4728,22 @@ def test_vecself(self):
47284728
p = np.inner(a, a)
47294729
assert_almost_equal(p, 0, decimal=14)
47304730

4731+
def test_inner_product_with_various_contiguities(self):
4732+
# github issue 6532
4733+
for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
4734+
# check an inner product involving a matrix transpose
4735+
A = np.array([[1, 2], [3, 4]], dtype=dt)
4736+
B = np.array([[1, 3], [2, 4]], dtype=dt)
4737+
C = np.array([1, 1], dtype=dt)
4738+
desired = np.array([4, 6], dtype=dt)
4739+
assert_equal(np.inner(A.T, C), desired)
4740+
assert_equal(np.inner(B, C), desired)
4741+
# check an inner product involving an aliased and reversed view
4742+
a = np.arange(5).astype(dt)
4743+
b = a[::-1]
4744+
desired = np.array(10, dtype=dt).item()
4745+
assert_equal(np.inner(b, a), desired)
4746+
47314747

47324748
class TestSummarization(TestCase):
47334749
def test_1d(self):

0 commit comments

Comments
 (0)