summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/cblasfuncs.c105
-rw-r--r--numpy/core/src/multiarray/common.c100
-rw-r--r--numpy/core/src/multiarray/common.h13
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c98
4 files changed, 120 insertions, 196 deletions
diff --git a/numpy/core/src/multiarray/cblasfuncs.c b/numpy/core/src/multiarray/cblasfuncs.c
index c941bb29b..6460c5db1 100644
--- a/numpy/core/src/multiarray/cblasfuncs.c
+++ b/numpy/core/src/multiarray/cblasfuncs.c
@@ -12,32 +12,6 @@
#include "npy_cblas.h"
#include "arraytypes.h"
#include "common.h"
-#include "mem_overlap.h"
-
-
-/*
- * Helper: call appropriate BLAS dot function for typenum.
- * Strides are NumPy strides.
- */
-static void
-blas_dot(int typenum, npy_intp n,
- void *a, npy_intp stridea, void *b, npy_intp strideb, void *res)
-{
- switch (typenum) {
- case NPY_DOUBLE:
- DOUBLE_dot(a, stridea, b, strideb, res, n, NULL);
- break;
- case NPY_FLOAT:
- FLOAT_dot(a, stridea, b, strideb, res, n, NULL);
- break;
- case NPY_CDOUBLE:
- CDOUBLE_dot(a, stridea, b, strideb, res, n, NULL);
- break;
- case NPY_CFLOAT:
- CFLOAT_dot(a, stridea, b, strideb, res, n, NULL);
- break;
- }
-}
static const double oneD[2] = {1.0, 0.0}, zeroD[2] = {0.0, 0.0};
@@ -227,6 +201,7 @@ _bad_strides(PyArrayObject *ap)
return 0;
}
+
/*
* dot(a,b)
* Returns the dot product of a and b for arrays of floating point types.
@@ -379,77 +354,9 @@ cblas_matrixproduct(int typenum, PyArrayObject *ap1, PyArrayObject *ap2,
}
}
- if (out != NULL) {
- int d;
-
- /* verify that out is usable */
- if (PyArray_NDIM(out) != nd ||
- PyArray_TYPE(out) != typenum ||
- !PyArray_ISCARRAY(out)) {
-
- PyErr_SetString(PyExc_ValueError,
- "output array is not acceptable (must have the right datatype, "
- "number of dimensions, and be a C-Array)");
- goto fail;
- }
- for (d = 0; d < nd; ++d) {
- if (dimensions[d] != PyArray_DIM(out, d)) {
- PyErr_SetString(PyExc_ValueError,
- "output array has wrong dimensions");
- goto fail;
- }
- }
-
- /* check for memory overlap */
- if (!(solve_may_share_memory(out, ap1, 1) == 0 &&
- solve_may_share_memory(out, ap2, 1) == 0)) {
- /* allocate temporary output array */
- out_buf = (PyArrayObject *)PyArray_NewLikeArray(out, NPY_CORDER,
- NULL, 0);
- if (out_buf == NULL) {
- goto fail;
- }
-
- /* set copy-back */
- Py_INCREF(out);
- if (PyArray_SetWritebackIfCopyBase(out_buf, out) < 0) {
- Py_DECREF(out);
- goto fail;
- }
- }
- else {
- Py_INCREF(out);
- out_buf = out;
- }
- Py_INCREF(out);
- result = out;
- }
- else {
- double prior1, prior2;
- PyTypeObject *subtype;
- PyObject *tmp;
-
- /* Choose which subtype to return */
- if (Py_TYPE(ap1) != Py_TYPE(ap2)) {
- prior2 = PyArray_GetPriority((PyObject *)ap2, 0.0);
- prior1 = PyArray_GetPriority((PyObject *)ap1, 0.0);
- subtype = (prior2 > prior1 ? Py_TYPE(ap2) : Py_TYPE(ap1));
- }
- else {
- prior1 = prior2 = 0.0;
- subtype = Py_TYPE(ap1);
- }
-
- tmp = (PyObject *)(prior2 > prior1 ? ap2 : ap1);
-
- out_buf = (PyArrayObject *)PyArray_New(subtype, nd, dimensions,
- typenum, NULL, NULL, 0, 0, tmp);
- if (out_buf == NULL) {
- goto fail;
- }
-
- Py_INCREF(out_buf);
- result = out_buf;
+ out_buf = new_array_for_sum(ap1, ap2, out, nd, dimensions, typenum, &result);
+ if (out_buf == NULL) {
+ goto fail;
}
numbytes = PyArray_NBYTES(out_buf);
@@ -617,10 +524,10 @@ cblas_matrixproduct(int typenum, PyArrayObject *ap1, PyArrayObject *ap2,
NPY_BEGIN_ALLOW_THREADS;
/* Dot product between two vectors -- Level 1 BLAS */
- blas_dot(typenum, l,
+ PyArray_DESCR(out_buf)->f->dotfunc(
PyArray_DATA(ap1), PyArray_STRIDE(ap1, (ap1shape == _row)),
PyArray_DATA(ap2), PyArray_STRIDE(ap2, 0),
- PyArray_DATA(out_buf));
+ PyArray_DATA(out_buf), l, NULL);
NPY_END_ALLOW_THREADS;
}
else if (ap1shape == _matrix && ap2shape != _matrix) {
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index c70f8526e..4f695fdc7 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -15,6 +15,7 @@
#include "buffer.h"
#include "get_attr_string.h"
+#include "mem_overlap.h"
/*
* The casting to use for implicit assignment operations resulting from
@@ -852,3 +853,102 @@ _may_have_objects(PyArray_Descr *dtype)
return (PyDataType_HASFIELDS(base) ||
PyDataType_FLAGCHK(base, NPY_ITEM_HASOBJECT) );
}
+
+/*
+ * Make a new empty array, of the passed size, of a type that takes the
+ * priority of ap1 and ap2 into account.
+ *
+ * If `out` is non-NULL, memory overlap is checked with ap1 and ap2, and an
+ * updateifcopy temporary array may be returned. If `result` is non-NULL, the
+ * output array to be returned (`out` if non-NULL and the newly allocated array
+ * otherwise) is incref'd and put to *result.
+ */
+NPY_NO_EXPORT PyArrayObject *
+new_array_for_sum(PyArrayObject *ap1, PyArrayObject *ap2, PyArrayObject* out,
+ int nd, npy_intp dimensions[], int typenum, PyArrayObject **result)
+{
+ PyArrayObject *out_buf;
+
+ if (out) {
+ int d;
+
+ /* verify that out is usable */
+ if (PyArray_NDIM(out) != nd ||
+ PyArray_TYPE(out) != typenum ||
+ !PyArray_ISCARRAY(out)) {
+ PyErr_SetString(PyExc_ValueError,
+ "output array is not acceptable (must have the right datatype, "
+ "number of dimensions, and be a C-Array)");
+ return 0;
+ }
+ for (d = 0; d < nd; ++d) {
+ if (dimensions[d] != PyArray_DIM(out, d)) {
+ PyErr_SetString(PyExc_ValueError,
+ "output array has wrong dimensions");
+ return 0;
+ }
+ }
+
+ /* check for memory overlap */
+ if (!(solve_may_share_memory(out, ap1, 1) == 0 &&
+ solve_may_share_memory(out, ap2, 1) == 0)) {
+ /* allocate temporary output array */
+ out_buf = (PyArrayObject *)PyArray_NewLikeArray(out, NPY_CORDER,
+ NULL, 0);
+ if (out_buf == NULL) {
+ return NULL;
+ }
+
+ /* set copy-back */
+ Py_INCREF(out);
+ if (PyArray_SetWritebackIfCopyBase(out_buf, out) < 0) {
+ Py_DECREF(out);
+ Py_DECREF(out_buf);
+ return NULL;
+ }
+ }
+ else {
+ Py_INCREF(out);
+ out_buf = out;
+ }
+
+ if (result) {
+ Py_INCREF(out);
+ *result = out;
+ }
+
+ return out_buf;
+ }
+ else {
+ PyTypeObject *subtype;
+ double prior1, prior2;
+ /*
+ * Need to choose an output array that can hold a sum
+ * -- use priority to determine which subtype.
+ */
+ if (Py_TYPE(ap2) != Py_TYPE(ap1)) {
+ prior2 = PyArray_GetPriority((PyObject *)ap2, 0.0);
+ prior1 = PyArray_GetPriority((PyObject *)ap1, 0.0);
+ subtype = (prior2 > prior1 ? Py_TYPE(ap2) : Py_TYPE(ap1));
+ }
+ else {
+ prior1 = prior2 = 0.0;
+ subtype = Py_TYPE(ap1);
+ }
+
+ out_buf = (PyArrayObject *)PyArray_New(subtype, nd, dimensions,
+ typenum, NULL, NULL, 0, 0,
+ (PyObject *)
+ (prior2 > prior1 ? ap2 : ap1));
+
+ if (out_buf != NULL && result) {
+ Py_INCREF(out_buf);
+ *result = out_buf;
+ }
+
+ return out_buf;
+ }
+}
+
+
+
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index ae9b960c8..db0a49920 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -283,4 +283,17 @@ blas_stride(npy_intp stride, unsigned itemsize)
#include "ucsnarrow.h"
+/*
+ * Make a new empty array, of the passed size, of a type that takes the
+ * priority of ap1 and ap2 into account.
+ *
+ * If `out` is non-NULL, memory overlap is checked with ap1 and ap2, and an
+ * updateifcopy temporary array may be returned. If `result` is non-NULL, the
+ * output array to be returned (`out` if non-NULL and the newly allocated array
+ * otherwise) is incref'd and put to *result.
+ */
+NPY_NO_EXPORT PyArrayObject *
+new_array_for_sum(PyArrayObject *ap1, PyArrayObject *ap2, PyArrayObject* out,
+ int nd, npy_intp dimensions[], int typenum, PyArrayObject **result);
+
#endif
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index f78a748c0..e6af5a81e 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -800,102 +800,6 @@ PyArray_CanCoerceScalar(int thistype, int neededtype,
return 0;
}
-/*
- * Make a new empty array, of the passed size, of a type that takes the
- * priority of ap1 and ap2 into account.
- *
- * If `out` is non-NULL, memory overlap is checked with ap1 and ap2, and an
- * updateifcopy temporary array may be returned. If `result` is non-NULL, the
- * output array to be returned (`out` if non-NULL and the newly allocated array
- * otherwise) is incref'd and put to *result.
- */
-static PyArrayObject *
-new_array_for_sum(PyArrayObject *ap1, PyArrayObject *ap2, PyArrayObject* out,
- int nd, npy_intp dimensions[], int typenum, PyArrayObject **result)
-{
- PyArrayObject *out_buf;
-
- if (out) {
- int d;
-
- /* verify that out is usable */
- if (PyArray_NDIM(out) != nd ||
- PyArray_TYPE(out) != typenum ||
- !PyArray_ISCARRAY(out)) {
- PyErr_SetString(PyExc_ValueError,
- "output array is not acceptable (must have the right datatype, "
- "number of dimensions, and be a C-Array)");
- return 0;
- }
- for (d = 0; d < nd; ++d) {
- if (dimensions[d] != PyArray_DIM(out, d)) {
- PyErr_SetString(PyExc_ValueError,
- "output array has wrong dimensions");
- return 0;
- }
- }
-
- /* check for memory overlap */
- if (!(solve_may_share_memory(out, ap1, 1) == 0 &&
- solve_may_share_memory(out, ap2, 1) == 0)) {
- /* allocate temporary output array */
- out_buf = (PyArrayObject *)PyArray_NewLikeArray(out, NPY_CORDER,
- NULL, 0);
- if (out_buf == NULL) {
- return NULL;
- }
-
- /* set copy-back */
- Py_INCREF(out);
- if (PyArray_SetWritebackIfCopyBase(out_buf, out) < 0) {
- Py_DECREF(out);
- Py_DECREF(out_buf);
- return NULL;
- }
- }
- else {
- Py_INCREF(out);
- out_buf = out;
- }
-
- if (result) {
- Py_INCREF(out);
- *result = out;
- }
-
- return out_buf;
- }
- else {
- PyTypeObject *subtype;
- double prior1, prior2;
- /*
- * Need to choose an output array that can hold a sum
- * -- use priority to determine which subtype.
- */
- if (Py_TYPE(ap2) != Py_TYPE(ap1)) {
- prior2 = PyArray_GetPriority((PyObject *)ap2, 0.0);
- prior1 = PyArray_GetPriority((PyObject *)ap1, 0.0);
- subtype = (prior2 > prior1 ? Py_TYPE(ap2) : Py_TYPE(ap1));
- }
- else {
- prior1 = prior2 = 0.0;
- subtype = Py_TYPE(ap1);
- }
-
- out_buf = (PyArrayObject *)PyArray_New(subtype, nd, dimensions,
- typenum, NULL, NULL, 0, 0,
- (PyObject *)
- (prior2 > prior1 ? ap2 : ap1));
-
- if (out_buf != NULL && result) {
- Py_INCREF(out_buf);
- *result = out_buf;
- }
-
- return out_buf;
- }
-}
-
/* Could perhaps be redone to not make contiguous arrays */
/*NUMPY_API
@@ -1101,7 +1005,7 @@ PyArray_MatrixProduct2(PyObject *op1, PyObject *op2, PyArrayObject* out)
NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap2));
while (it1->index < it1->size) {
while (it2->index < it2->size) {
- dot(it1->dataptr, is1, it2->dataptr, is2, op, l, out_buf);
+ dot(it1->dataptr, is1, it2->dataptr, is2, op, l, NULL);
op += os;
PyArray_ITER_NEXT(it2);
}