numpy  2.0.0
src/multiarray/common.h
Go to the documentation of this file.
00001 #ifndef _NPY_PRIVATE_COMMON_H_
00002 #define _NPY_PRIVATE_COMMON_H_
00003 #include <numpy/npy_common.h>
00004 #include <numpy/npy_cpu.h>
00005 #include <numpy/ndarraytypes.h>
00006 #include <limits.h>
00007 
00008 #define error_converting(x)  (((x) == -1) && PyErr_Occurred())
00009 
00010 #ifdef NPY_ALLOW_THREADS
00011 #define NPY_BEGIN_THREADS_NDITER(iter) \
00012         do { \
00013             if (!NpyIter_IterationNeedsAPI(iter)) { \
00014                 NPY_BEGIN_THREADS_THRESHOLDED(NpyIter_GetIterSize(iter)); \
00015             } \
00016         } while(0)
00017 #else
00018 #define NPY_BEGIN_THREADS_NDITER(iter)
00019 #endif
00020 
00021 /*
00022  * Recursively examines the object to determine an appropriate dtype
00023  * to use for converting to an ndarray.
00024  *
00025  * 'obj' is the object to be converted to an ndarray.
00026  *
00027  * 'maxdims' is the maximum recursion depth.
00028  *
00029  * 'out_dtype' should be either NULL or a minimal starting dtype when
00030  * the function is called. It is updated with the results of type
00031  * promotion. This dtype does not get updated when processing NA objects.
00032  *
00033  * Returns 0 on success, -1 on failure.
00034  */
00035 NPY_NO_EXPORT int
00036 PyArray_DTypeFromObject(PyObject *obj, int maxdims,
00037                         PyArray_Descr **out_dtype);
00038 
00039 NPY_NO_EXPORT int
00040 PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
00041                               PyArray_Descr **out_dtype, int string_status);
00042 
00043 NPY_NO_EXPORT PyObject *
00044 PyArray_GetAttrString_SuppressException(PyObject *v, char *name);
00045 
00046 /*
00047  * Returns NULL without setting an exception if no scalar is matched, a
00048  * new dtype reference otherwise.
00049  */
00050 NPY_NO_EXPORT PyArray_Descr *
00051 _array_find_python_scalar_type(PyObject *op);
00052 
00053 NPY_NO_EXPORT PyArray_Descr *
00054 _array_typedescr_fromstr(char *str);
00055 
00056 NPY_NO_EXPORT char *
00057 index2ptr(PyArrayObject *mp, npy_intp i);
00058 
00059 NPY_NO_EXPORT int
00060 _zerofill(PyArrayObject *ret);
00061 
00062 NPY_NO_EXPORT int
00063 _IsAligned(PyArrayObject *ap);
00064 
00065 NPY_NO_EXPORT npy_bool
00066 _IsWriteable(PyArrayObject *ap);
00067 
00068 NPY_NO_EXPORT PyObject *
00069 convert_shape_to_string(npy_intp n, npy_intp *vals, char *ending);
00070 
00071 /*
00072  * Sets ValueError with "matrices not aligned" message for np.dot and friends
00073  * when a.shape[i] should match b.shape[j], but doesn't.
00074  */
00075 NPY_NO_EXPORT void
00076 dot_alignment_error(PyArrayObject *a, int i, PyArrayObject *b, int j);
00077 
00088 NPY_NO_EXPORT int
00089 _unpack_field(PyObject *value, PyArray_Descr **descr, npy_intp *offset);
00090 
00091 /*
00092  * check whether arrays with datatype dtype might have object fields. This will
00093  * only happen for structured dtypes (which may have hidden objects even if the
00094  * HASOBJECT flag is false), object dtypes, or subarray dtypes whose base type
00095  * is either of these.
00096  */
00097 NPY_NO_EXPORT int
00098 _may_have_objects(PyArray_Descr *dtype);
00099 
00100 /*
00101  * Returns -1 and sets an exception if *index is an invalid index for
00102  * an array of size max_item, otherwise adjusts it in place to be
00103  * 0 <= *index < max_item, and returns 0.
00104  * 'axis' should be the array axis that is being indexed over, if known. If
00105  * unknown, use -1.
00106  * If _save is NULL it is assumed the GIL is taken
00107  * If _save is not NULL it is assumed the GIL is not taken and it
00108  * is acquired in the case of an error
00109  */
00110 static NPY_INLINE int
00111 check_and_adjust_index(npy_intp *index, npy_intp max_item, int axis,
00112                        PyThreadState * _save)
00113 {
00114     /* Check that index is valid, taking into account negative indices */
00115     if (NPY_UNLIKELY((*index < -max_item) || (*index >= max_item))) {
00116         NPY_END_THREADS;
00117         /* Try to be as clear as possible about what went wrong. */
00118         if (axis >= 0) {
00119             PyErr_Format(PyExc_IndexError,
00120                          "index %"NPY_INTP_FMT" is out of bounds "
00121                          "for axis %d with size %"NPY_INTP_FMT,
00122                          *index, axis, max_item);
00123         } else {
00124             PyErr_Format(PyExc_IndexError,
00125                          "index %"NPY_INTP_FMT" is out of bounds "
00126                          "for size %"NPY_INTP_FMT, *index, max_item);
00127         }
00128         return -1;
00129     }
00130     /* adjust negative indices */
00131     if (*index < 0) {
00132         *index += max_item;
00133     }
00134     return 0;
00135 }
00136 
00137 
00138 /*
00139  * return true if pointer is aligned to 'alignment'
00140  */
00141 static NPY_INLINE int
00142 npy_is_aligned(const void * p, const npy_uintp alignment)
00143 {
00144     /*
00145      * alignment is usually a power of two
00146      * the test is faster than a direct modulo
00147      */
00148     if (NPY_LIKELY((alignment & (alignment - 1)) == 0)) {
00149         return ((npy_uintp)(p) & ((alignment) - 1)) == 0;
00150     }
00151     else {
00152         return ((npy_uintp)(p) % alignment) == 0;
00153     }
00154 }
00155 
00156 /*
00157  * memchr with stride and invert argument
00158  * intended for small searches where a call out to libc memchr is costly.
00159  * stride must be a multiple of size.
00160  * compared to memchr it returns one stride past end instead of NULL if needle
00161  * is not found.
00162  */
00163 static NPY_INLINE char *
00164 npy_memchr(char * haystack, char needle,
00165            npy_intp stride, npy_intp size, npy_intp * psubloopsize, int invert)
00166 {
00167     char * p = haystack;
00168     npy_intp subloopsize = 0;
00169 
00170     if (!invert) {
00171         /*
00172          * this is usually the path to determine elements to process,
00173          * performance less important here.
00174          * memchr has large setup cost if 0 byte is close to start.
00175          */
00176         while (subloopsize < size && *p != needle) {
00177             subloopsize++;
00178             p += stride;
00179         }
00180     }
00181     else {
00182         /* usually find elements to skip path */
00183         if (NPY_CPU_HAVE_UNALIGNED_ACCESS && needle == 0 && stride == 1) {
00184             /* iterate until last multiple of 4 */
00185             char * block_end = haystack + size - (size % sizeof(unsigned int));
00186             while (p < block_end) {
00187                 unsigned int  v = *(unsigned int*)p;
00188                 if (v != 0) {
00189                     break;
00190                 }
00191                 p += sizeof(unsigned int);
00192             }
00193             /* handle rest */
00194             subloopsize = (p - haystack);
00195         }
00196         while (subloopsize < size && *p == needle) {
00197             subloopsize++;
00198             p += stride;
00199         }
00200     }
00201 
00202     *psubloopsize = subloopsize;
00203 
00204     return p;
00205 }
00206 
00207 static NPY_INLINE int
00208 _is_basic_python_type(PyObject * obj)
00209 {
00210     if (obj == Py_None ||
00211             PyBool_Check(obj) ||
00212             /* Basic number types */
00213 #if !defined(NPY_PY3K)
00214             PyInt_CheckExact(obj) ||
00215             PyString_CheckExact(obj) ||
00216 #endif
00217             PyLong_CheckExact(obj) ||
00218             PyFloat_CheckExact(obj) ||
00219             PyComplex_CheckExact(obj) ||
00220             /* Basic sequence types */
00221             PyList_CheckExact(obj) ||
00222             PyTuple_CheckExact(obj) ||
00223             PyDict_CheckExact(obj) ||
00224             PyAnySet_CheckExact(obj) ||
00225             PyUnicode_CheckExact(obj) ||
00226             PyBytes_CheckExact(obj) ||
00227             PySlice_Check(obj)) {
00228 
00229         return 1;
00230     }
00231 
00232     return 0;
00233 }
00234 
00235 /*
00236  * Convert NumPy stride to BLAS stride. Returns 0 if conversion cannot be done
00237  * (BLAS won't handle negative or zero strides the way we want).
00238  */
00239 static NPY_INLINE int
00240 blas_stride(npy_intp stride, unsigned itemsize)
00241 {
00242     /*
00243      * Should probably check pointer alignment also, but this may cause
00244      * problems if we require complex to be 16 byte aligned.
00245      */
00246     if (stride > 0 && npy_is_aligned((void *)stride, itemsize)) {
00247         stride /= itemsize;
00248         if (stride <= INT_MAX) {
00249             return stride;
00250         }
00251     }
00252     return 0;
00253 }
00254 
00255 /*
00256  * Define a chunksize for CBLAS. CBLAS counts in integers.
00257  */
00258 #if NPY_MAX_INTP > INT_MAX
00259 # define NPY_CBLAS_CHUNK  (INT_MAX / 2 + 1)
00260 #else
00261 # define NPY_CBLAS_CHUNK  NPY_MAX_INTP
00262 #endif
00263 
00264 #include "ucsnarrow.h"
00265 
00266 #endif