numpy 2.0.0
|
00001 #ifndef Py_UFUNCOBJECT_H 00002 #define Py_UFUNCOBJECT_H 00003 00004 #include <numpy/npy_math.h> 00005 00006 #ifdef __cplusplus 00007 extern "C" { 00008 #endif 00009 00010 typedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *); 00011 00012 typedef struct { 00013 PyObject_HEAD 00014 /* 00015 * nin: Number of inputs 00016 * nout: Number of outputs 00017 * nargs: Always nin + nout (Why is it stored?) 00018 */ 00019 int nin, nout, nargs; 00020 00021 /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */ 00022 int identity; 00023 00024 /* Array of one-dimensional core loops */ 00025 PyUFuncGenericFunction *functions; 00026 /* Array of funcdata that gets passed into the functions */ 00027 void **data; 00028 /* The number of elements in 'functions' and 'data' */ 00029 int ntypes; 00030 00031 /* Does not appear to be used */ 00032 int check_return; 00033 00034 /* The name of the ufunc */ 00035 char *name; 00036 00037 /* Array of type numbers, of size ('nargs' * 'ntypes') */ 00038 char *types; 00039 00040 /* Documentation string */ 00041 char *doc; 00042 00043 void *ptr; 00044 PyObject *obj; 00045 PyObject *userloops; 00046 00047 /* generalized ufunc parameters */ 00048 00049 /* 0 for scalar ufunc; 1 for generalized ufunc */ 00050 int core_enabled; 00051 /* number of distinct dimension names in signature */ 00052 int core_num_dim_ix; 00053 00054 /* 00055 * dimension indices of input/output argument k are stored in 00056 * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1] 00057 */ 00058 00059 /* numbers of core dimensions of each argument */ 00060 int *core_num_dims; 00061 /* 00062 * dimension indices in a flatted form; indices 00063 * are in the range of [0,core_num_dim_ix) 00064 */ 00065 int *core_dim_ixs; 00066 /* 00067 * positions of 1st core dimensions of each 00068 * argument in core_dim_ixs 00069 */ 00070 int *core_offsets; 00071 /* signature string for printing purpose */ 00072 char *core_signature; 00073 } PyUFuncObject; 00074 00075 #include "arrayobject.h" 00076 00077 #define UFUNC_ERR_IGNORE 0 00078 #define UFUNC_ERR_WARN 1 00079 #define UFUNC_ERR_RAISE 2 00080 #define UFUNC_ERR_CALL 3 00081 #define UFUNC_ERR_PRINT 4 00082 #define UFUNC_ERR_LOG 5 00083 00084 /* Python side integer mask */ 00085 00086 #define UFUNC_MASK_DIVIDEBYZERO 0x07 00087 #define UFUNC_MASK_OVERFLOW 0x3f 00088 #define UFUNC_MASK_UNDERFLOW 0x1ff 00089 #define UFUNC_MASK_INVALID 0xfff 00090 00091 #define UFUNC_SHIFT_DIVIDEBYZERO 0 00092 #define UFUNC_SHIFT_OVERFLOW 3 00093 #define UFUNC_SHIFT_UNDERFLOW 6 00094 #define UFUNC_SHIFT_INVALID 9 00095 00096 00097 /* platform-dependent code translates floating point 00098 status to an integer sum of these values 00099 */ 00100 #define UFUNC_FPE_DIVIDEBYZERO 1 00101 #define UFUNC_FPE_OVERFLOW 2 00102 #define UFUNC_FPE_UNDERFLOW 4 00103 #define UFUNC_FPE_INVALID 8 00104 00105 /* Error mode that avoids look-up (no checking) */ 00106 #define UFUNC_ERR_DEFAULT 0 00107 00108 #define UFUNC_OBJ_ISOBJECT 1 00109 #define UFUNC_OBJ_NEEDS_API 2 00110 00111 /* Default user error mode */ 00112 #define UFUNC_ERR_DEFAULT2 \ 00113 (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) + \ 00114 (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) + \ 00115 (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID) 00116 00117 #if NPY_ALLOW_THREADS 00118 #define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0) 00119 #define NPY_LOOP_END_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0) 00120 #else 00121 #define NPY_LOOP_BEGIN_THREADS 00122 #define NPY_LOOP_END_THREADS 00123 #endif 00124 00125 #define PyUFunc_One 1 00126 #define PyUFunc_Zero 0 00127 #define PyUFunc_None -1 00128 00129 #define UFUNC_REDUCE 0 00130 #define UFUNC_ACCUMULATE 1 00131 #define UFUNC_REDUCEAT 2 00132 #define UFUNC_OUTER 3 00133 00134 00135 typedef struct { 00136 int nin; 00137 int nout; 00138 PyObject *callable; 00139 } PyUFunc_PyFuncData; 00140 00141 /* A linked-list of function information for 00142 user-defined 1-d loops. 00143 */ 00144 typedef struct _loop1d_info { 00145 PyUFuncGenericFunction func; 00146 void *data; 00147 int *arg_types; 00148 struct _loop1d_info *next; 00149 } PyUFunc_Loop1d; 00150 00151 00152 #include "__ufunc_api.h" 00153 00154 #define UFUNC_PYVALS_NAME "UFUNC_PYVALS" 00155 00156 #define UFUNC_CHECK_ERROR(arg) \ 00157 do {if ((((arg)->obj & UFUNC_OBJ_NEEDS_API) && PyErr_Occurred()) || \ 00158 ((arg)->errormask && \ 00159 PyUFunc_checkfperr((arg)->errormask, \ 00160 (arg)->errobj, \ 00161 &(arg)->first))) \ 00162 goto fail;} while (0) 00163 00164 /* This code checks the IEEE status flags in a platform-dependent way */ 00165 /* Adapted from Numarray */ 00166 00167 #if (defined(__unix__) || defined(unix)) && !defined(USG) 00168 #include <sys/param.h> 00169 #endif 00170 00171 /* OSF/Alpha (Tru64) ---------------------------------------------*/ 00172 #if defined(__osf__) && defined(__alpha) 00173 00174 #include <machine/fpu.h> 00175 00176 #define UFUNC_CHECK_STATUS(ret) { \ 00177 unsigned long fpstatus; \ 00178 \ 00179 fpstatus = ieee_get_fp_control(); \ 00180 /* clear status bits as well as disable exception mode if on */ \ 00181 ieee_set_fp_control( 0 ); \ 00182 ret = ((IEEE_STATUS_DZE & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \ 00183 | ((IEEE_STATUS_OVF & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \ 00184 | ((IEEE_STATUS_UNF & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \ 00185 | ((IEEE_STATUS_INV & fpstatus) ? UFUNC_FPE_INVALID : 0); \ 00186 } 00187 00188 /* MS Windows -----------------------------------------------------*/ 00189 #elif defined(_MSC_VER) 00190 00191 #include <float.h> 00192 00193 /* Clear the floating point exception default of Borland C++ */ 00194 #if defined(__BORLANDC__) 00195 #define UFUNC_NOFPE _control87(MCW_EM, MCW_EM); 00196 #endif 00197 00198 #define UFUNC_CHECK_STATUS(ret) { \ 00199 int fpstatus = (int) _clearfp(); \ 00200 \ 00201 ret = ((SW_ZERODIVIDE & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \ 00202 | ((SW_OVERFLOW & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \ 00203 | ((SW_UNDERFLOW & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \ 00204 | ((SW_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0); \ 00205 } 00206 00207 /* Solaris --------------------------------------------------------*/ 00208 /* --------ignoring SunOS ieee_flags approach, someone else can 00209 ** deal with that! */ 00210 #elif defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \ 00211 (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \ 00212 defined(__NetBSD__) 00213 #include <ieeefp.h> 00214 00215 #define UFUNC_CHECK_STATUS(ret) { \ 00216 int fpstatus; \ 00217 \ 00218 fpstatus = (int) fpgetsticky(); \ 00219 ret = ((FP_X_DZ & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \ 00220 | ((FP_X_OFL & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \ 00221 | ((FP_X_UFL & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \ 00222 | ((FP_X_INV & fpstatus) ? UFUNC_FPE_INVALID : 0); \ 00223 (void) fpsetsticky(0); \ 00224 } 00225 00226 #elif defined(__GLIBC__) || defined(__APPLE__) || \ 00227 defined(__CYGWIN__) || defined(__MINGW32__) || \ 00228 (defined(__FreeBSD__) && (__FreeBSD_version >= 502114)) 00229 00230 #if defined(__GLIBC__) || defined(__APPLE__) || \ 00231 defined(__MINGW32__) || defined(__FreeBSD__) 00232 #include <fenv.h> 00233 #elif defined(__CYGWIN__) 00234 #include "fenv/fenv.c" 00235 #endif 00236 00237 #define UFUNC_CHECK_STATUS(ret) { \ 00238 int fpstatus = (int) fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | \ 00239 FE_UNDERFLOW | FE_INVALID); \ 00240 ret = ((FE_DIVBYZERO & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \ 00241 | ((FE_OVERFLOW & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \ 00242 | ((FE_UNDERFLOW & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \ 00243 | ((FE_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0); \ 00244 (void) feclearexcept(FE_DIVBYZERO | FE_OVERFLOW | \ 00245 FE_UNDERFLOW | FE_INVALID); \ 00246 } 00247 00248 #elif defined(_AIX) 00249 00250 #include <float.h> 00251 #include <fpxcp.h> 00252 00253 #define UFUNC_CHECK_STATUS(ret) { \ 00254 fpflag_t fpstatus; \ 00255 \ 00256 fpstatus = fp_read_flag(); \ 00257 ret = ((FP_DIV_BY_ZERO & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \ 00258 | ((FP_OVERFLOW & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \ 00259 | ((FP_UNDERFLOW & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \ 00260 | ((FP_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0); \ 00261 fp_swap_flag(0); \ 00262 } 00263 00264 #else 00265 00266 #define NO_FLOATING_POINT_SUPPORT 00267 #define UFUNC_CHECK_STATUS(ret) { \ 00268 ret = 0; \ 00269 } 00270 00271 #endif 00272 00273 /* 00274 * THESE MACROS ARE DEPRECATED. 00275 * Use npy_set_floatstatus_* in the npymath library. 00276 */ 00277 #define generate_divbyzero_error() npy_set_floatstatus_divbyzero() 00278 #define generate_overflow_error() npy_set_floatstatus_overflow() 00279 00280 /* Make sure it gets defined if it isn't already */ 00281 #ifndef UFUNC_NOFPE 00282 #define UFUNC_NOFPE 00283 #endif 00284 00285 00286 #ifdef __cplusplus 00287 } 00288 #endif 00289 #endif /* !Py_UFUNCOBJECT_H */