1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
|
#if !defined(_ndarraymacro)
#define _ndarraymacro
#include <Python.h>
/* The structs defined here are private implementation details of numarray
which are subject to change w/o notice.
*/
typedef struct
{
long in1, in2, out, thread_id;
char cumop[12];
PyObject *type;
PyObject *ctuple;
} _cache_entry;
typedef struct
{
int insert;
_cache_entry entry[20];
} _ufunc_cache;
typedef PyObject *(*_ufunc_function)(PyObject *ufunc,
int n_ins, PyObject *ins[],
int n_outs, PyObject*outs[]);
typedef struct {
PyObject_HEAD
PyObject *oprator; /* ufunc name */
PyObject *identity; /* identity value, e.g. 0 for + or 1 for * */
int n_inputs, n_outputs;
_ufunc_function call;
_ufunc_cache cache;
} PyUfuncObject;
typedef struct {
PyObject_HEAD
PyObject *(*compute)(PyObject*,PyObject*,PyObject*); /* Must match PyOperatorObject */
PyObject *(*rebuffer)(PyObject*,PyObject*,PyObject*);
void (*clean)(PyObject*,PyObject*);
int arr_position;
int inb_position;
int direction;
int generated;
int conversion_required;
PyObject *buffers[4];
PyObject *bytestrides[2];
PyObject *convfunction;
PyObject *stridefunction;
PyObject *result_buff;
} PyConverterObject;
typedef struct {
PyObject_HEAD
PyObject *(*compute)(PyObject*,PyObject*,PyObject*); /* Must match PyConverterObject */
PyObject *inputs;
PyObject *outputs;
PyObject *cfunc;
int striding;
} PyOperatorObject;
#define PY_BOOL_CHAR "b"
#define PY_INT8_CHAR "b"
#define PY_INT16_CHAR "h"
#define PY_INT32_CHAR "i"
#define PY_FLOAT32_CHAR "f"
#define PY_FLOAT64_CHAR "d"
#define PY_UINT8_CHAR "h"
#define PY_UINT16_CHAR "i"
#define PY_UINT32_CHAR "i" /* Unless longer int available */
#define PY_COMPLEX64_CHAR "D"
#define PY_COMPLEX128_CHAR "D"
#define PY_LONG_CHAR "l"
#define PY_LONG_LONG_CHAR "L"
#define pyFPE_DIVIDE_BY_ZERO 1
#define pyFPE_OVERFLOW 2
#define pyFPE_UNDERFLOW 4
#define pyFPE_INVALID 8
#define isNonZERO(x) (x != 0) /* to convert values to boolean 1's or 0's */
typedef enum
{
NUM_CONTIGUOUS=1,
NUM_NOTSWAPPED=2,
NUM_ALIGNED=4,
NUM_WRITABLE=8,
NUM_COPY=16,
NUM_C_ARRAY = (NUM_CONTIGUOUS | NUM_ALIGNED | NUM_NOTSWAPPED),
NUM_UNCONVERTED = 0
} NumRequirements;
#define UNCONVERTED 0
#define C_ARRAY (NUM_CONTIGUOUS | NUM_NOTSWAPPED | NUM_ALIGNED)
#define MUST_BE_COMPUTED 2
#define NUM_FLOORDIVIDE(a,b,out) (out) = floor((a)/(b))
#define NA_Begin() Py_Initialize(); import_libnumarray();
#define NA_End() NA_Done(); Py_Finalize();
#define NA_OFFSETDATA(num) ((void *) num->data)
/* unaligned NA_COPY functions */
#define NA_COPY1(i, o) (*(o) = *(i))
#define NA_COPY2(i, o) NA_COPY1(i, o), NA_COPY1(i+1, o+1)
#define NA_COPY4(i, o) NA_COPY2(i, o), NA_COPY2(i+2, o+2)
#define NA_COPY8(i, o) NA_COPY4(i, o), NA_COPY4(i+4, o+4)
#define NA_COPY16(i, o) NA_COPY8(i, o), NA_COPY8(i+8, o+8)
/* byteswapping macros: these fail if i==o */
#define NA_SWAP1(i, o) NA_COPY1(i, o)
#define NA_SWAP2(i, o) NA_SWAP1(i, o+1), NA_SWAP1(i+1, o)
#define NA_SWAP4(i, o) NA_SWAP2(i, o+2), NA_SWAP2(i+2, o)
#define NA_SWAP8(i, o) NA_SWAP4(i, o+4), NA_SWAP4(i+4, o)
#define NA_SWAP16(i, o) NA_SWAP8(i, o+8), NA_SWAP8(i+8, o)
/* complex byteswaps must swap each part (real, imag) independently */
#define NA_COMPLEX_SWAP8(i, o) NA_SWAP4(i, o), NA_SWAP4(i+4, o+4)
#define NA_COMPLEX_SWAP16(i, o) NA_SWAP8(i, o), NA_SWAP8(i+8, o+8)
/* byteswapping macros: these work even if i == o */
#define NA_TSWAP1(i, o, t) NA_COPY1(i, t), NA_SWAP1(t, o)
#define NA_TSWAP2(i, o, t) NA_COPY2(i, t), NA_SWAP2(t, o)
#define NA_TSWAP4(i, o, t) NA_COPY4(i, t), NA_SWAP4(t, o)
#define NA_TSWAP8(i, o, t) NA_COPY8(i, t), NA_SWAP8(t, o)
/* fast copy functions for %N aligned i and o */
#define NA_ACOPY1(i, o) (((Int8 *)o)[0] = ((Int8 *)i)[0])
#define NA_ACOPY2(i, o) (((Int16 *)o)[0] = ((Int16 *)i)[0])
#define NA_ACOPY4(i, o) (((Int32 *)o)[0] = ((Int32 *)i)[0])
#define NA_ACOPY8(i, o) (((Float64 *)o)[0] = ((Float64 *)i)[0])
#define NA_ACOPY16(i, o) (((Complex64 *)o)[0] = ((Complex64 *)i)[0])
/* from here down, type("ai") is NDInfo* */
#define NA_PTR(ai) ((char *) NA_OFFSETDATA((ai)))
#define NA_TEMP(ai) ((char *) &((ai)->temp))
#define NA_PTR1(ai, i) (NA_PTR(ai) + \
(i)*(ai)->strides[0])
#define NA_PTR2(ai, i, j) (NA_PTR(ai) + \
(i)*(ai)->strides[0] + \
(j)*(ai)->strides[1])
#define NA_PTR3(ai, i, j, k) (NA_PTR(ai) + \
(i)*(ai)->strides[0] + \
(j)*(ai)->strides[1] + \
(k)*(ai)->strides[2])
#define NA_RESULT(ai, type) (*((type *) NA_TEMP(ai)))
#define NA_SET_TEMP(ai, type, v) (((type *) &(ai)->temp)[0] = v)
#define NA_SWAPComplex64 NA_COMPLEX_SWAP16
#define NA_SWAPComplex32 NA_COMPLEX_SWAP8
#define NA_SWAPFloat64 NA_SWAP8
#define NA_SWAPFloat32 NA_SWAP4
#define NA_SWAPInt64 NA_SWAP8
#define NA_SWAPUInt64 NA_SWAP8
#define NA_SWAPInt32 NA_SWAP4
#define NA_SWAPUInt32 NA_SWAP4
#define NA_SWAPInt16 NA_SWAP2
#define NA_SWAPUInt16 NA_SWAP2
#define NA_SWAPInt8 NA_SWAP1
#define NA_SWAPUInt8 NA_SWAP1
#define NA_SWAPBool NA_SWAP1
#define NA_COPYComplex64 NA_COPY16
#define NA_COPYComplex32 NA_COPY8
#define NA_COPYFloat64 NA_COPY8
#define NA_COPYFloat32 NA_COPY4
#define NA_COPYInt64 NA_COPY8
#define NA_COPYUInt64 NA_COPY8
#define NA_COPYInt32 NA_COPY4
#define NA_COPYUInt32 NA_COPY4
#define NA_COPYInt16 NA_COPY2
#define NA_COPYUInt16 NA_COPY2
#define NA_COPYInt8 NA_COPY1
#define NA_COPYUInt8 NA_COPY1
#define NA_COPYBool NA_COPY1
#define NA_REM(ai, ptr) ((ai)->wptr = (ptr))
#define NA_REC(ai) ((ai)->wptr)
/* ========================== ptr get/set ================================ */
/* byteswapping */
#define NA_GETPb(ai, type, ptr) \
(NA_REM(ai, ptr), NA_SWAP##type(NA_REC(ai), NA_TEMP(ai)), \
NA_RESULT(ai, type))
/* aligning */
#define NA_GETPa(ai, type, ptr) \
(NA_REM(ai, ptr), NA_COPY##type(NA_REC(ai), NA_TEMP(ai)), \
NA_RESULT(ai, type))
/* fast (aligned, !byteswapped) */
#define NA_GETPf(ai, type, ptr) (*((type *) (ptr)))
#define NA_GETP(ai, type, ptr) \
(PyArray_ISCARRAY(ai) ? NA_GETPf(ai, type, ptr) \
: (PyArray_ISBYTESWAPPED(ai) ? \
NA_GETPb(ai, type, ptr) \
: NA_GETPa(ai, type, ptr)))
/* NOTE: NA_SET* macros cannot be used as values. */
/* byteswapping */
#define NA_SETPb(ai, type, ptr, v) \
(NA_REM(ai, ptr), NA_SET_TEMP(ai, type, v), \
NA_SWAP##type(NA_TEMP(ai), NA_REC(ai)))
/* aligning */
#define NA_SETPa(ai, type, ptr, v) \
(NA_REM(ai, ptr), NA_SET_TEMP(ai, type, v), \
NA_COPY##type(NA_TEMP(ai), NA_REC(ai)))
/* fast (aligned, !byteswapped) */
#define NA_SETPf(ai, type, ptr, v) ((*((type *) ptr)) = (v))
#define NA_SETP(ai, type, ptr, v) \
if (PyArray_ISCARRAY(ai)) { \
NA_SETPf((ai), type, (ptr), (v)); \
} else if (PyArray_ISBYTESWAPPED(ai)) { \
NA_SETPb((ai), type, (ptr), (v)); \
} else \
NA_SETPa((ai), type, (ptr), (v))
/* ========================== 1 index get/set ============================ */
/* byteswapping */
#define NA_GET1b(ai, type, i) NA_GETPb(ai, type, NA_PTR1(ai, i))
/* aligning */
#define NA_GET1a(ai, type, i) NA_GETPa(ai, type, NA_PTR1(ai, i))
/* fast (aligned, !byteswapped) */
#define NA_GET1f(ai, type, i) NA_GETPf(ai, type, NA_PTR1(ai, i))
/* testing */
#define NA_GET1(ai, type, i) NA_GETP(ai, type, NA_PTR1(ai, i))
/* byteswapping */
#define NA_SET1b(ai, type, i, v) NA_SETPb(ai, type, NA_PTR1(ai, i), v)
/* aligning */
#define NA_SET1a(ai, type, i, v) NA_SETPa(ai, type, NA_PTR1(ai, i), v)
/* fast (aligned, !byteswapped) */
#define NA_SET1f(ai, type, i, v) NA_SETPf(ai, type, NA_PTR1(ai, i), v)
/* testing */
#define NA_SET1(ai, type, i, v) NA_SETP(ai, type, NA_PTR1(ai, i), v)
/* ========================== 2 index get/set ============================= */
/* byteswapping */
#define NA_GET2b(ai, type, i, j) NA_GETPb(ai, type, NA_PTR2(ai, i, j))
/* aligning */
#define NA_GET2a(ai, type, i, j) NA_GETPa(ai, type, NA_PTR2(ai, i, j))
/* fast (aligned, !byteswapped) */
#define NA_GET2f(ai, type, i, j) NA_GETPf(ai, type, NA_PTR2(ai, i, j))
/* testing */
#define NA_GET2(ai, type, i, j) NA_GETP(ai, type, NA_PTR2(ai, i, j))
/* byteswapping */
#define NA_SET2b(ai, type, i, j, v) NA_SETPb(ai, type, NA_PTR2(ai, i, j), v)
/* aligning */
#define NA_SET2a(ai, type, i, j, v) NA_SETPa(ai, type, NA_PTR2(ai, i, j), v)
/* fast (aligned, !byteswapped) */
#define NA_SET2f(ai, type, i, j, v) NA_SETPf(ai, type, NA_PTR2(ai, i, j), v)
#define NA_SET2(ai, type, i, j, v) NA_SETP(ai, type, NA_PTR2(ai, i, j), v)
/* ========================== 3 index get/set ============================= */
/* byteswapping */
#define NA_GET3b(ai, type, i, j, k) NA_GETPb(ai, type, NA_PTR3(ai, i, j, k))
/* aligning */
#define NA_GET3a(ai, type, i, j, k) NA_GETPa(ai, type, NA_PTR3(ai, i, j, k))
/* fast (aligned, !byteswapped) */
#define NA_GET3f(ai, type, i, j, k) NA_GETPf(ai, type, NA_PTR3(ai, i, j, k))
/* testing */
#define NA_GET3(ai, type, i, j, k) NA_GETP(ai, type, NA_PTR3(ai, i, j, k))
/* byteswapping */
#define NA_SET3b(ai, type, i, j, k, v) \
NA_SETPb(ai, type, NA_PTR3(ai, i, j, k), v)
/* aligning */
#define NA_SET3a(ai, type, i, j, k, v) \
NA_SETPa(ai, type, NA_PTR3(ai, i, j, k), v)
/* fast (aligned, !byteswapped) */
#define NA_SET3f(ai, type, i, j, k, v) \
NA_SETPf(ai, type, NA_PTR3(ai, i, j, k), v)
#define NA_SET3(ai, type, i, j, k, v) \
NA_SETP(ai, type, NA_PTR3(ai, i, j, k), v)
/* ========================== 1D get/set ================================== */
#define NA_GET1Db(ai, type, base, cnt, out) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
out[i] = NA_GETPb(ai, type, base); \
base += stride; \
} \
}
#define NA_GET1Da(ai, type, base, cnt, out) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
out[i] = NA_GETPa(ai, type, base); \
base += stride; \
} \
}
#define NA_GET1Df(ai, type, base, cnt, out) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
out[i] = NA_GETPf(ai, type, base); \
base += stride; \
} \
}
#define NA_GET1D(ai, type, base, cnt, out) \
if (PyArray_ISCARRAY(ai)) { \
NA_GET1Df(ai, type, base, cnt, out); \
} else if (PyArray_ISBYTESWAPPED(ai)) { \
NA_GET1Db(ai, type, base, cnt, out); \
} else { \
NA_GET1Da(ai, type, base, cnt, out); \
}
#define NA_SET1Db(ai, type, base, cnt, in) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
NA_SETPb(ai, type, base, in[i]); \
base += stride; \
} \
}
#define NA_SET1Da(ai, type, base, cnt, in) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
NA_SETPa(ai, type, base, in[i]); \
base += stride; \
} \
}
#define NA_SET1Df(ai, type, base, cnt, in) \
{ int i, stride = ai->strides[ai->nd-1]; \
for(i=0; i<cnt; i++) { \
NA_SETPf(ai, type, base, in[i]); \
base += stride; \
} \
}
#define NA_SET1D(ai, type, base, cnt, out) \
if (PyArray_ISCARRAY(ai)) { \
NA_SET1Df(ai, type, base, cnt, out); \
} else if (PyArray_ISBYTESWAPPED(ai)) { \
NA_SET1Db(ai, type, base, cnt, out); \
} else { \
NA_SET1Da(ai, type, base, cnt, out); \
}
/* ========================== utilities ================================== */
#if !defined(MIN)
#define MIN(x,y) (((x)<=(y)) ? (x) : (y))
#endif
#if !defined(MAX)
#define MAX(x,y) (((x)>=(y)) ? (x) : (y))
#endif
#if !defined(ABS)
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#endif
#define ELEM(x) (sizeof(x)/sizeof(x[0]))
#define BOOLEAN_BITWISE_NOT(x) ((x) ^ 1)
#define NA_NBYTES(a) (a->descr->elsize * NA_elements(a))
#if defined(NA_SMP)
#define BEGIN_THREADS Py_BEGIN_ALLOW_THREADS
#define END_THREADS Py_END_ALLOW_THREADS
#else
#define BEGIN_THREADS
#define END_THREADS
#endif
#include "numconfig.h"
#define ADD_VERSION(m) \
if (PyModule_AddObject(m, "__version__", \
PyString_FromString(NUMARRAY_VERSION)) < 0) \
return;
#if !defined(NA_isnan)
#define U32(u) (* (Int32 *) &(u) )
#define U64(u) (* (Int64 *) &(u) )
#define NA_isnan32(u) \
( (( U32(u) & 0x7f800000) == 0x7f800000) && ((U32(u) & 0x007fffff) != 0)) ? 1:0
#if !defined(_MSC_VER)
#define NA_isnan64(u) \
( (( U64(u) & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) && ((U64(u) & 0x000fffffffffffffLL) != 0)) ? 1:0
#else
#define NA_isnan64(u) \
( (( U64(u) & 0x7ff0000000000000i64) == 0x7ff0000000000000i64) && ((U64(u) & 0x000fffffffffffffi64) != 0)) ? 1:0
#endif
#define NA_isnanC32(u) (NA_isnan32(((Complex32 *)&(u))->r) || NA_isnan32(((Complex32 *)&(u))->i))
#define NA_isnanC64(u) (NA_isnan64(((Complex64 *)&(u))->r) || NA_isnan64(((Complex64 *)&(u))->i))
#endif /* NA_isnan */
#if PY_VERSION_HEX < 0x02030000
#define PyBool_FromLong PyInt_FromLong
#endif
#endif /* _ndarraymacro */
|