summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorLars Buitinck <larsmans@gmail.com>2014-08-23 22:30:07 +0200
committerLars Buitinck <larsmans@gmail.com>2014-08-24 13:27:49 +0200
commitd07c4c72793fc120bf4cc807857567517e775c5b (patch)
tree2313c12b7c999da0765b14a90139335a2e2b5bb9 /numpy
parentd8af083f3873da3fa041f20d1b981709cc61d972 (diff)
downloadnumpy-d07c4c72793fc120bf4cc807857567517e775c5b.tar.gz
ENH: include shapes in "matrices not aligned" msg
I had to move convert_shape_to_string to common.h so that _dotblas.c can access it.
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/blasdot/_dotblas.c10
-rw-r--r--numpy/core/src/multiarray/common.c61
-rw-r--r--numpy/core/src/multiarray/common.h119
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c6
4 files changed, 117 insertions, 79 deletions
diff --git a/numpy/core/blasdot/_dotblas.c b/numpy/core/blasdot/_dotblas.c
index a16cbe5d0..0679e38f8 100644
--- a/numpy/core/blasdot/_dotblas.c
+++ b/numpy/core/blasdot/_dotblas.c
@@ -530,8 +530,7 @@ dotblas_matrixproduct(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject* kwa
l = PyArray_DIM(oap1, PyArray_NDIM(oap1) - 1);
if (PyArray_DIM(oap2, 0) != l) {
- not_aligned(PyArray_NDIM(oap1) - 1, 0,
- l, PyArray_DIM(oap2, 0));
+ not_aligned(oap1, PyArray_NDIM(oap1) - 1, oap2, 0);
goto fail;
}
nd = PyArray_NDIM(ap1) + PyArray_NDIM(ap2) - 2;
@@ -581,8 +580,7 @@ dotblas_matrixproduct(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject* kwa
l = PyArray_DIM(ap1, PyArray_NDIM(ap1) - 1);
if (PyArray_DIM(ap2, 0) != l) {
- not_aligned(PyArray_NDIM(ap1) - 1, 0,
- l, PyArray_DIM(ap2, 0));
+ not_aligned(ap1, PyArray_NDIM(ap1) - 1, ap2, 0);
goto fail;
}
nd = PyArray_NDIM(ap1) + PyArray_NDIM(ap2) - 2;
@@ -1010,8 +1008,8 @@ dotblas_innerproduct(PyObject *NPY_UNUSED(dummy), PyObject *args)
l = PyArray_DIM(ap1, PyArray_NDIM(ap1)-1);
if (PyArray_DIM(ap2, PyArray_NDIM(ap2)-1) != l) {
- not_aligned(PyArray_NDIM(ap1) - 1, PyArray_NDIM(ap2) - 1,
- l, PyArray_DIM(ap2, PyArray_NDIM(ap2) - 1));
+ not_aligned(ap1, PyArray_NDIM(ap1) - 1,
+ ap2, PyArray_NDIM(ap2) - 1);
goto fail;
}
nd = PyArray_NDIM(ap1)+PyArray_NDIM(ap2)-2;
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 54b9e3c1a..02f16b9bc 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -779,64 +779,3 @@ offset_bounds_from_strides(const int itemsize, const int nd,
*lower_offset = lower;
*upper_offset = upper;
}
-
-
-/**
- * Convert an array shape to a string such as "(1, 2)".
- *
- * @param Dimensionality of the shape
- * @param npy_intp pointer to shape array
- * @param String to append after the shape `(1, 2)%s`.
- *
- * @return Python unicode string
- */
-NPY_NO_EXPORT PyObject *
-convert_shape_to_string(npy_intp n, npy_intp *vals, char *ending)
-{
- npy_intp i;
- PyObject *ret, *tmp;
-
- /*
- * Negative dimension indicates "newaxis", which can
- * be discarded for printing if it's a leading dimension.
- * Find the first non-"newaxis" dimension.
- */
- for (i = 0; i < n && vals[i] < 0; i++);
-
- if (i == n) {
- return PyUString_FromFormat("()%s", ending);
- }
- else {
- ret = PyUString_FromFormat("(%" NPY_INTP_FMT, vals[i++]);
- if (ret == NULL) {
- return NULL;
- }
- }
-
- for (; i < n; ++i) {
- if (vals[i] < 0) {
- tmp = PyUString_FromString(",newaxis");
- }
- else {
- tmp = PyUString_FromFormat(",%" NPY_INTP_FMT, vals[i]);
- }
- if (tmp == NULL) {
- Py_DECREF(ret);
- return NULL;
- }
-
- PyUString_ConcatAndDel(&ret, tmp);
- if (ret == NULL) {
- return NULL;
- }
- }
-
- if (i == 1) {
- tmp = PyUString_FromFormat(",)%s", ending);
- }
- else {
- tmp = PyUString_FromFormat(")%s", ending);
- }
- PyUString_ConcatAndDel(&ret, tmp);
- return ret;
-}
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index 5edf4e6ba..2de31e467 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -3,6 +3,7 @@
#include <numpy/npy_common.h>
#include <numpy/npy_cpu.h>
#include <numpy/ndarraytypes.h>
+#include <numpy/npy_3kcompat.h>
#define error_converting(x) (((x) == -1) && PyErr_Occurred())
@@ -69,9 +70,6 @@ offset_bounds_from_strides(const int itemsize, const int nd,
const npy_intp *dims, const npy_intp *strides,
npy_intp *lower_offset, npy_intp *upper_offset);
-NPY_NO_EXPORT PyObject *
-convert_shape_to_string(npy_intp n, npy_intp *vals, char *ending);
-
/*
* Returns -1 and sets an exception if *index is an invalid index for
@@ -208,16 +206,121 @@ _is_basic_python_type(PyObject * obj)
return 0;
}
+
+/**
+ * Convert an array shape to a string such as "(1, 2)".
+ *
+ * @param Dimensionality of the shape
+ * @param npy_intp pointer to shape array
+ * @param String to append after the shape `(1, 2)%s`.
+ *
+ * @return Python unicode string
+ */
+static NPY_INLINE PyObject *
+convert_shape_to_string(npy_intp n, npy_intp *vals, char *ending)
+{
+ npy_intp i;
+ PyObject *ret, *tmp;
+
+ /*
+ * Negative dimension indicates "newaxis", which can
+ * be discarded for printing if it's a leading dimension.
+ * Find the first non-"newaxis" dimension.
+ */
+ for (i = 0; i < n && vals[i] < 0; i++);
+
+ if (i == n) {
+ return PyUString_FromFormat("()%s", ending);
+ }
+ else {
+ ret = PyUString_FromFormat("(%" NPY_INTP_FMT, vals[i++]);
+ if (ret == NULL) {
+ return NULL;
+ }
+ }
+
+ for (; i < n; ++i) {
+ if (vals[i] < 0) {
+ tmp = PyUString_FromString(",newaxis");
+ }
+ else {
+ tmp = PyUString_FromFormat(",%" NPY_INTP_FMT, vals[i]);
+ }
+ if (tmp == NULL) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ PyUString_ConcatAndDel(&ret, tmp);
+ if (ret == NULL) {
+ return NULL;
+ }
+ }
+
+ if (i == 1) {
+ tmp = PyUString_FromFormat(",)%s", ending);
+ }
+ else {
+ tmp = PyUString_FromFormat(")%s", ending);
+ }
+ PyUString_ConcatAndDel(&ret, tmp);
+ return ret;
+}
+
+
/*
* Sets ValueError with "matrices not aligned" message for np.dot and friends
- * when shape[i] = m doesn't match shape[j] = n.
+ * when a.shape[i] should match b.shape[j], but doesn't.
*/
static NPY_INLINE void
-not_aligned(int i, int j, Py_ssize_t m, Py_ssize_t n)
+not_aligned(PyArrayObject *a, int i, PyArrayObject *b, int j)
{
- PyErr_Format(PyExc_ValueError,
- "matrices are not aligned: shape[%d] (%zd) != shape[%d] (%zd)",
- i, m, j, n);
+ PyObject *errmsg = NULL, *format = NULL, *fmt_args = NULL,
+ *i_obj = NULL, *j_obj = NULL,
+ *shape1 = NULL, *shape2 = NULL,
+ *shape1_i = NULL, *shape2_j = NULL;
+
+ format = PyUString_FromString("shapes %s and %s not aligned:"
+ " %d (dim %d) != %d (dim %d)");
+
+ shape1 = convert_shape_to_string(PyArray_NDIM(a), PyArray_DIMS(a), "");
+ shape2 = convert_shape_to_string(PyArray_NDIM(b), PyArray_DIMS(b), "");
+
+ i_obj = PyLong_FromLong(i);
+ j_obj = PyLong_FromLong(j);
+
+ shape1_i = PyLong_FromSsize_t(PyArray_DIM(a, i));
+ shape2_j = PyLong_FromSsize_t(PyArray_DIM(b, j));
+
+ if (!format || !shape1 || !shape2 || !i_obj || !j_obj ||
+ !shape1_i || !shape2_j) {
+ goto end;
+ }
+
+ fmt_args = PyTuple_Pack(6, shape1, shape2,
+ shape1_i, i_obj, shape2_j, j_obj);
+ if (fmt_args == NULL) {
+ goto end;
+ }
+
+ errmsg = PyUString_Format(format, fmt_args);
+ if (errmsg != NULL) {
+ PyErr_SetObject(PyExc_ValueError, errmsg);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "shapes are not aligned");
+ }
+
+end:
+ Py_XDECREF(errmsg);
+ Py_XDECREF(fmt_args);
+ Py_XDECREF(format);
+ Py_XDECREF(i_obj);
+ Py_XDECREF(j_obj);
+ Py_XDECREF(shape1);
+ Py_XDECREF(shape2);
+ Py_XDECREF(shape1_i);
+ Py_XDECREF(shape2_j);
}
#include "ucsnarrow.h"
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index a3165b67c..8f5bb6d4a 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -841,8 +841,7 @@ PyArray_InnerProduct(PyObject *op1, PyObject *op2)
l = PyArray_DIMS(ap1)[PyArray_NDIM(ap1) - 1];
if (PyArray_DIMS(ap2)[PyArray_NDIM(ap2) - 1] != l) {
- not_aligned(PyArray_NDIM(ap1) - 1, PyArray_NDIM(ap2) - 1,
- l, PyArray_DIMS(ap2)[PyArray_NDIM(ap2) - 1]);
+ not_aligned(ap1, PyArray_NDIM(ap1) - 1, ap2, PyArray_NDIM(ap2) - 1);
goto fail;
}
@@ -962,8 +961,7 @@ PyArray_MatrixProduct2(PyObject *op1, PyObject *op2, PyArrayObject* out)
matchDim = 0;
}
if (PyArray_DIMS(ap2)[matchDim] != l) {
- not_aligned(PyArray_NDIM(ap1) - 1, matchDim,
- l, PyArray_DIMS(ap2)[matchDim]);
+ not_aligned(ap1, PyArray_NDIM(ap1) - 1, ap2, matchDim);
goto fail;
}
nd = PyArray_NDIM(ap1) + PyArray_NDIM(ap2) - 2;