numpy
2.0.0
|
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