numexpr 2.10.2__cp313-cp313-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ #ifndef NUMEXPR_CONFIG_HPP
2
+ #define NUMEXPR_CONFIG_HPP
3
+
4
+ // x86 platform works with unaligned reads and writes
5
+ // MW: I have seen exceptions to this when the compiler chooses to use aligned SSE
6
+ #if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
7
+ # define USE_UNALIGNED_ACCESS 1
8
+ #endif
9
+
10
+ // #ifdef SCIPY_MKL_H
11
+ // #define USE_VML
12
+ // #endif
13
+
14
+ #ifdef USE_VML
15
+ /* The values below have been tuned for a Skylake processor (E3-1245 v5 @ 3.50GHz) */
16
+ #define BLOCK_SIZE1 1024
17
+ #else
18
+ /* The values below have been tuned for a Skylake processor (E3-1245 v5 @ 3.50GHz) */
19
+ #define BLOCK_SIZE1 1024
20
+ #endif
21
+
22
+ // The default threadpool size. It's prefer that the user set this via an
23
+ // environment variable, "NUMEXPR_MAX_THREADS"
24
+ #define DEFAULT_MAX_THREADS 64
25
+
26
+ // Remove dependence on NPY_MAXARGS, which would be a runtime constant instead of compiletime
27
+ // constant. If numpy raises NPY_MAXARGS, we should notice and raise this as well
28
+ #define NE_MAXARGS 64
29
+
30
+ #if defined(_WIN32)
31
+ #include "win32/pthread.h"
32
+ #include <process.h>
33
+ #define getpid _getpid
34
+ #else
35
+ #include <pthread.h>
36
+ #include "unistd.h"
37
+ #endif
38
+
39
+ #ifdef USE_VML
40
+ #include "mkl_vml.h"
41
+ #include "mkl_service.h"
42
+ #endif
43
+
44
+ #ifdef _WIN32
45
+ #ifndef __MINGW32__
46
+ #include "missing_posix_functions.hpp"
47
+ #endif
48
+ #include "msvc_function_stubs.hpp"
49
+ #endif
50
+
51
+ #endif // NUMEXPR_CONFIG_HPP
@@ -0,0 +1,408 @@
1
+ /*********************************************************************
2
+ Numexpr - Fast numerical array expression evaluator for NumPy.
3
+
4
+ License: MIT
5
+ Author: See AUTHORS.txt
6
+
7
+ See LICENSE.txt for details about copyright and rights to use.
8
+ **********************************************************************/
9
+
10
+ #include "module.hpp"
11
+ #include <structmember.h>
12
+
13
+ #include "numexpr_config.hpp"
14
+ #include "interpreter.hpp"
15
+ #include "numexpr_object.hpp"
16
+
17
+ static int
18
+ size_from_char(char c)
19
+ {
20
+ switch (c) {
21
+ case 'b': return sizeof(char);
22
+ case 'i': return sizeof(int);
23
+ case 'l': return sizeof(long long);
24
+ case 'f': return sizeof(float);
25
+ case 'd': return sizeof(double);
26
+ case 'c': return 2*sizeof(double);
27
+ case 's': return 0; /* strings are ok but size must be computed */
28
+ default:
29
+ PyErr_SetString(PyExc_TypeError, "signature value not in 'bilfdcs'");
30
+ return -1;
31
+ }
32
+ }
33
+
34
+ static void
35
+ NumExpr_dealloc(NumExprObject *self)
36
+ {
37
+ Py_XDECREF(self->signature);
38
+ Py_XDECREF(self->tempsig);
39
+ Py_XDECREF(self->constsig);
40
+ Py_XDECREF(self->fullsig);
41
+ Py_XDECREF(self->program);
42
+ Py_XDECREF(self->constants);
43
+ Py_XDECREF(self->input_names);
44
+ PyMem_Del(self->mem);
45
+ PyMem_Del(self->rawmem);
46
+ PyMem_Del(self->memsteps);
47
+ PyMem_Del(self->memsizes);
48
+ Py_TYPE(self)->tp_free((PyObject*)self);
49
+ }
50
+
51
+ static PyObject *
52
+ NumExpr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
53
+ {
54
+ NumExprObject *self = (NumExprObject *)type->tp_alloc(type, 0);
55
+ if (self != NULL) {
56
+ #define INIT_WITH(name, object) \
57
+ self->name = object; \
58
+ if (!self->name) { \
59
+ Py_DECREF(self); \
60
+ return NULL; \
61
+ }
62
+
63
+ INIT_WITH(signature, PyBytes_FromString(""));
64
+ INIT_WITH(tempsig, PyBytes_FromString(""));
65
+ INIT_WITH(constsig, PyBytes_FromString(""));
66
+ INIT_WITH(fullsig, PyBytes_FromString(""));
67
+ INIT_WITH(program, PyBytes_FromString(""));
68
+ INIT_WITH(constants, PyTuple_New(0));
69
+ Py_INCREF(Py_None);
70
+ self->input_names = Py_None;
71
+ self->mem = NULL;
72
+ self->rawmem = NULL;
73
+ self->memsteps = NULL;
74
+ self->memsizes = NULL;
75
+ self->rawmemsize = 0;
76
+ self->n_inputs = 0;
77
+ self->n_constants = 0;
78
+ self->n_temps = 0;
79
+ #undef INIT_WITH
80
+ }
81
+ return (PyObject *)self;
82
+ }
83
+
84
+ #define CHARP(s) ((char *)(s))
85
+
86
+ static int
87
+ NumExpr_init(NumExprObject *self, PyObject *args, PyObject *kwds)
88
+ {
89
+ int i, j, mem_offset;
90
+ int n_inputs, n_constants, n_temps;
91
+ PyObject *signature = NULL, *tempsig = NULL, *constsig = NULL;
92
+ PyObject *fullsig = NULL, *program = NULL, *constants = NULL;
93
+ PyObject *input_names = NULL, *o_constants = NULL;
94
+ int *itemsizes = NULL;
95
+ char **mem = NULL, *rawmem = NULL;
96
+ npy_intp *memsteps;
97
+ npy_intp *memsizes;
98
+ int rawmemsize;
99
+ static char *kwlist[] = {CHARP("signature"), CHARP("tempsig"),
100
+ CHARP("program"), CHARP("constants"),
101
+ CHARP("input_names"), NULL};
102
+
103
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SSS|OO", kwlist,
104
+ &signature,
105
+ &tempsig,
106
+ &program, &o_constants,
107
+ &input_names)) {
108
+ return -1;
109
+ }
110
+
111
+ n_inputs = (int)PyBytes_Size(signature);
112
+ n_temps = (int)PyBytes_Size(tempsig);
113
+
114
+ if (o_constants) {
115
+ if (!PySequence_Check(o_constants) ) {
116
+ PyErr_SetString(PyExc_TypeError, "constants must be a sequence");
117
+ return -1;
118
+ }
119
+ n_constants = (int)PySequence_Length(o_constants);
120
+ if (!(constants = PyTuple_New(n_constants)))
121
+ return -1;
122
+ if (!(constsig = PyBytes_FromStringAndSize(NULL, n_constants))) {
123
+ Py_DECREF(constants);
124
+ return -1;
125
+ }
126
+ if (!(itemsizes = PyMem_New(int, n_constants))) {
127
+ Py_DECREF(constants);
128
+ return -1;
129
+ }
130
+ for (i = 0; i < n_constants; i++) {
131
+ PyObject *o;
132
+ if (!(o = PySequence_GetItem(o_constants, i))) { /* new reference */
133
+ Py_DECREF(constants);
134
+ Py_DECREF(constsig);
135
+ PyMem_Del(itemsizes);
136
+ return -1;
137
+ }
138
+ PyTuple_SET_ITEM(constants, i, o); /* steals reference */
139
+ if (PyBool_Check(o)) {
140
+ PyBytes_AS_STRING(constsig)[i] = 'b';
141
+ itemsizes[i] = size_from_char('b');
142
+ continue;
143
+ }
144
+
145
+ if (PyArray_IsScalar(o, Int32)) {
146
+ PyBytes_AS_STRING(constsig)[i] = 'i';
147
+ itemsizes[i] = size_from_char('i');
148
+ continue;
149
+ }
150
+
151
+ if (PyArray_IsScalar(o, Int64)) {
152
+ PyBytes_AS_STRING(constsig)[i] = 'l';
153
+ itemsizes[i] = size_from_char('l');
154
+ continue;
155
+ }
156
+ /* The Float32 scalars are the only ones that should reach here */
157
+ if (PyArray_IsScalar(o, Float32)) {
158
+ PyBytes_AS_STRING(constsig)[i] = 'f';
159
+ itemsizes[i] = size_from_char('f');
160
+ continue;
161
+ }
162
+ if (PyFloat_Check(o)) {
163
+ /* Python float constants are double precision by default */
164
+ PyBytes_AS_STRING(constsig)[i] = 'd';
165
+ itemsizes[i] = size_from_char('d');
166
+ continue;
167
+ }
168
+ if (PyComplex_Check(o)) {
169
+ PyBytes_AS_STRING(constsig)[i] = 'c';
170
+ itemsizes[i] = size_from_char('c');
171
+ continue;
172
+ }
173
+ if (PyBytes_Check(o)) {
174
+ PyBytes_AS_STRING(constsig)[i] = 's';
175
+ itemsizes[i] = (int)PyBytes_GET_SIZE(o);
176
+ continue;
177
+ }
178
+ PyErr_SetString(PyExc_TypeError, "constants must be of type bool/int/long/float/double/complex/bytes");
179
+ Py_DECREF(constsig);
180
+ Py_DECREF(constants);
181
+ PyMem_Del(itemsizes);
182
+ return -1;
183
+ }
184
+ } else {
185
+ n_constants = 0;
186
+ if (!(constants = PyTuple_New(0)))
187
+ return -1;
188
+ if (!(constsig = PyBytes_FromString(""))) {
189
+ Py_DECREF(constants);
190
+ return -1;
191
+ }
192
+ }
193
+
194
+ fullsig = PyBytes_FromFormat("%c%s%s%s", get_return_sig(program),
195
+ PyBytes_AS_STRING(signature), PyBytes_AS_STRING(constsig),
196
+ PyBytes_AS_STRING(tempsig));
197
+ if (!fullsig) {
198
+ Py_DECREF(constants);
199
+ Py_DECREF(constsig);
200
+ PyMem_Del(itemsizes);
201
+ return -1;
202
+ }
203
+
204
+ if (!input_names) {
205
+ input_names = Py_None;
206
+ }
207
+
208
+ /* Compute the size of registers. We leave temps out (will be
209
+ malloc'ed later on). */
210
+ rawmemsize = 0;
211
+ for (i = 0; i < n_constants; i++)
212
+ rawmemsize += itemsizes[i];
213
+ rawmemsize *= BLOCK_SIZE1;
214
+
215
+ mem = PyMem_New(char *, 1 + n_inputs + n_constants + n_temps);
216
+ rawmem = PyMem_New(char, rawmemsize);
217
+ memsteps = PyMem_New(npy_intp, 1 + n_inputs + n_constants + n_temps);
218
+ memsizes = PyMem_New(npy_intp, 1 + n_inputs + n_constants + n_temps);
219
+ if (!mem || !rawmem || !memsteps || !memsizes) {
220
+ Py_DECREF(constants);
221
+ Py_DECREF(constsig);
222
+ Py_DECREF(fullsig);
223
+ PyMem_Del(itemsizes);
224
+ PyMem_Del(mem);
225
+ PyMem_Del(rawmem);
226
+ PyMem_Del(memsteps);
227
+ PyMem_Del(memsizes);
228
+ return -1;
229
+ }
230
+ /*
231
+ 0 -> output
232
+ [1, n_inputs+1) -> inputs
233
+ [n_inputs+1, n_inputs+n_consts+1) -> constants
234
+ [n_inputs+n_consts+1, n_inputs+n_consts+n_temps+1) -> temps
235
+ */
236
+ /* Fill in 'mem' and 'rawmem' for constants */
237
+ mem_offset = 0;
238
+ for (i = 0; i < n_constants; i++) {
239
+ char c = PyBytes_AS_STRING(constsig)[i];
240
+ int size = itemsizes[i];
241
+ mem[i+n_inputs+1] = rawmem + mem_offset;
242
+ mem_offset += BLOCK_SIZE1 * size;
243
+ memsteps[i+n_inputs+1] = memsizes[i+n_inputs+1] = size;
244
+ /* fill in the constants */
245
+ if (c == 'b') {
246
+ char *bmem = (char*)mem[i+n_inputs+1];
247
+ char value = (char)PyLong_AsLong(PyTuple_GET_ITEM(constants, i));
248
+ for (j = 0; j < BLOCK_SIZE1; j++) {
249
+ bmem[j] = value;
250
+ }
251
+ } else if (c == 'i') {
252
+ int *imem = (int*)mem[i+n_inputs+1];
253
+ int value = (int)PyLong_AsLong(PyTuple_GET_ITEM(constants, i));
254
+ for (j = 0; j < BLOCK_SIZE1; j++) {
255
+ imem[j] = value;
256
+ }
257
+ } else if (c == 'l') {
258
+ long long *lmem = (long long*)mem[i+n_inputs+1];
259
+ long long value = PyLong_AsLongLong(PyTuple_GET_ITEM(constants, i));
260
+ for (j = 0; j < BLOCK_SIZE1; j++) {
261
+ lmem[j] = value;
262
+ }
263
+ } else if (c == 'f') {
264
+ /* In this particular case the constant is in a NumPy scalar
265
+ and in a regular Python object */
266
+ float *fmem = (float*)mem[i+n_inputs+1];
267
+ float value = PyArrayScalar_VAL(PyTuple_GET_ITEM(constants, i),
268
+ Float);
269
+ for (j = 0; j < BLOCK_SIZE1; j++) {
270
+ fmem[j] = value;
271
+ }
272
+ } else if (c == 'd') {
273
+ double *dmem = (double*)mem[i+n_inputs+1];
274
+ double value = PyFloat_AS_DOUBLE(PyTuple_GET_ITEM(constants, i));
275
+ for (j = 0; j < BLOCK_SIZE1; j++) {
276
+ dmem[j] = value;
277
+ }
278
+ } else if (c == 'c') {
279
+ double *cmem = (double*)mem[i+n_inputs+1];
280
+ Py_complex value = PyComplex_AsCComplex(PyTuple_GET_ITEM(constants, i));
281
+ for (j = 0; j < 2*BLOCK_SIZE1; j+=2) {
282
+ cmem[j] = value.real;
283
+ cmem[j+1] = value.imag;
284
+ }
285
+ } else if (c == 's') {
286
+ char *smem = (char*)mem[i+n_inputs+1];
287
+ char *value = PyBytes_AS_STRING(PyTuple_GET_ITEM(constants, i));
288
+ for (j = 0; j < size*BLOCK_SIZE1; j+=size) {
289
+ memcpy(smem + j, value, size);
290
+ }
291
+ }
292
+ }
293
+ /* This is no longer needed since no unusual item sizes appear
294
+ in temporaries (there are no string temporaries). */
295
+ PyMem_Del(itemsizes);
296
+
297
+ /* Fill in 'memsteps' and 'memsizes' for temps */
298
+ for (i = 0; i < n_temps; i++) {
299
+ char c = PyBytes_AS_STRING(tempsig)[i];
300
+ int size = size_from_char(c);
301
+ memsteps[i+n_inputs+n_constants+1] = size;
302
+ memsizes[i+n_inputs+n_constants+1] = size;
303
+ }
304
+ /* See if any errors occured (e.g., in size_from_char) or if mem_offset is wrong */
305
+ if (PyErr_Occurred() || mem_offset != rawmemsize) {
306
+ if (mem_offset != rawmemsize) {
307
+ PyErr_Format(PyExc_RuntimeError, "mem_offset does not match rawmemsize");
308
+ }
309
+ Py_DECREF(constants);
310
+ Py_DECREF(constsig);
311
+ Py_DECREF(fullsig);
312
+ PyMem_Del(mem);
313
+ PyMem_Del(rawmem);
314
+ PyMem_Del(memsteps);
315
+ PyMem_Del(memsizes);
316
+ return -1;
317
+ }
318
+
319
+
320
+ #define REPLACE_OBJ(arg) \
321
+ {PyObject *tmp = self->arg; \
322
+ self->arg = arg; \
323
+ Py_XDECREF(tmp);}
324
+ #define INCREF_REPLACE_OBJ(arg) {Py_INCREF(arg); REPLACE_OBJ(arg);}
325
+ #define REPLACE_MEM(arg) {PyMem_Del(self->arg); self->arg=arg;}
326
+
327
+ INCREF_REPLACE_OBJ(signature);
328
+ INCREF_REPLACE_OBJ(tempsig);
329
+ REPLACE_OBJ(constsig);
330
+ REPLACE_OBJ(fullsig);
331
+ INCREF_REPLACE_OBJ(program);
332
+ REPLACE_OBJ(constants);
333
+ INCREF_REPLACE_OBJ(input_names);
334
+ REPLACE_MEM(mem);
335
+ REPLACE_MEM(rawmem);
336
+ REPLACE_MEM(memsteps);
337
+ REPLACE_MEM(memsizes);
338
+ self->rawmemsize = rawmemsize;
339
+ self->n_inputs = n_inputs;
340
+ self->n_constants = n_constants;
341
+ self->n_temps = n_temps;
342
+
343
+ #undef REPLACE_OBJ
344
+ #undef INCREF_REPLACE_OBJ
345
+ #undef REPLACE_MEM
346
+
347
+ return check_program(self);
348
+ }
349
+
350
+ static PyMethodDef NumExpr_methods[] = {
351
+ {"run", (PyCFunction) NumExpr_run, METH_VARARGS|METH_KEYWORDS, NULL},
352
+ {NULL, NULL}
353
+ };
354
+
355
+ static PyMemberDef NumExpr_members[] = {
356
+ {CHARP("signature"), T_OBJECT_EX, offsetof(NumExprObject, signature), READONLY, NULL},
357
+ {CHARP("constsig"), T_OBJECT_EX, offsetof(NumExprObject, constsig), READONLY, NULL},
358
+ {CHARP("tempsig"), T_OBJECT_EX, offsetof(NumExprObject, tempsig), READONLY, NULL},
359
+ {CHARP("fullsig"), T_OBJECT_EX, offsetof(NumExprObject, fullsig), READONLY, NULL},
360
+
361
+ {CHARP("program"), T_OBJECT_EX, offsetof(NumExprObject, program), READONLY, NULL},
362
+ {CHARP("constants"), T_OBJECT_EX, offsetof(NumExprObject, constants),
363
+ READONLY, NULL},
364
+ {CHARP("input_names"), T_OBJECT, offsetof(NumExprObject, input_names), 0, NULL},
365
+ {NULL},
366
+ };
367
+
368
+ PyTypeObject NumExprType = {
369
+ PyVarObject_HEAD_INIT(NULL, 0)
370
+ "numexpr.NumExpr", /*tp_name*/
371
+ sizeof(NumExprObject), /*tp_basicsize*/
372
+ 0, /*tp_itemsize*/
373
+ (destructor)NumExpr_dealloc, /*tp_dealloc*/
374
+ 0, /*tp_print*/
375
+ 0, /*tp_getattr*/
376
+ 0, /*tp_setattr*/
377
+ 0, /*tp_compare*/
378
+ 0, /*tp_repr*/
379
+ 0, /*tp_as_number*/
380
+ 0, /*tp_as_sequence*/
381
+ 0, /*tp_as_mapping*/
382
+ 0, /*tp_hash */
383
+ (ternaryfunc)NumExpr_run, /*tp_call*/
384
+ 0, /*tp_str*/
385
+ 0, /*tp_getattro*/
386
+ 0, /*tp_setattro*/
387
+ 0, /*tp_as_buffer*/
388
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
389
+ "NumExpr objects", /* tp_doc */
390
+ 0, /* tp_traverse */
391
+ 0, /* tp_clear */
392
+ 0, /* tp_richcompare */
393
+ 0, /* tp_weaklistoffset */
394
+ 0, /* tp_iter */
395
+ 0, /* tp_iternext */
396
+ NumExpr_methods, /* tp_methods */
397
+ NumExpr_members, /* tp_members */
398
+ 0, /* tp_getset */
399
+ 0, /* tp_base */
400
+ 0, /* tp_dict */
401
+ 0, /* tp_descr_get */
402
+ 0, /* tp_descr_set */
403
+ 0, /* tp_dictoffset */
404
+ (initproc)NumExpr_init, /* tp_init */
405
+ 0, /* tp_alloc */
406
+ NumExpr_new, /* tp_new */
407
+ };
408
+
@@ -0,0 +1,34 @@
1
+ #ifndef NUMEXPR_OBJECT_HPP
2
+ #define NUMEXPR_OBJECT_HPP
3
+ /*********************************************************************
4
+ Numexpr - Fast numerical array expression evaluator for NumPy.
5
+
6
+ License: MIT
7
+ Author: See AUTHORS.txt
8
+
9
+ See LICENSE.txt for details about copyright and rights to use.
10
+ **********************************************************************/
11
+
12
+ struct NumExprObject
13
+ {
14
+ PyObject_HEAD
15
+ PyObject *signature; /* a python string */
16
+ PyObject *tempsig;
17
+ PyObject *constsig;
18
+ PyObject *fullsig;
19
+ PyObject *program; /* a python string */
20
+ PyObject *constants; /* a tuple of int/float/complex */
21
+ PyObject *input_names; /* tuple of strings */
22
+ char **mem; /* pointers to registers */
23
+ char *rawmem; /* a chunks of raw memory for storing registers */
24
+ npy_intp *memsteps;
25
+ npy_intp *memsizes;
26
+ int rawmemsize;
27
+ int n_inputs;
28
+ int n_constants;
29
+ int n_temps;
30
+ };
31
+
32
+ extern PyTypeObject NumExprType;
33
+
34
+ #endif // NUMEXPR_OBJECT_HPP
numexpr/opcodes.hpp ADDED
@@ -0,0 +1,179 @@
1
+ /*********************************************************************
2
+ Numexpr - Fast numerical array expression evaluator for NumPy.
3
+
4
+ License: MIT
5
+ Author: See AUTHORS.txt
6
+
7
+ See LICENSE.txt for details about copyright and rights to use.
8
+ **********************************************************************/
9
+
10
+ /*
11
+ OPCODE(n, enum_name, exported, return_type, arg1_type, arg2_type, arg3_type)
12
+
13
+ `exported` is NULL if the opcode shouldn't exported by the Python module.
14
+
15
+ Types are Tb, Ti, Tl, Tf, Td, Tc, Ts, Tn, and T0; these symbols should be
16
+ #defined to whatever is needed. (T0 is the no-such-arg type.)
17
+
18
+ */
19
+ OPCODE(0, OP_NOOP, "noop", T0, T0, T0, T0)
20
+
21
+ OPCODE(1, OP_COPY_BB, "copy_bb", Tb, Tb, T0, T0)
22
+
23
+ OPCODE(2, OP_INVERT_BB, "invert_bb", Tb, Tb, T0, T0)
24
+ OPCODE(3, OP_AND_BBB, "and_bbb", Tb, Tb, Tb, T0)
25
+ OPCODE(4, OP_OR_BBB, "or_bbb", Tb, Tb, Tb, T0)
26
+
27
+ OPCODE(5, OP_EQ_BBB, "eq_bbb", Tb, Tb, Tb, T0)
28
+ OPCODE(6, OP_NE_BBB, "ne_bbb", Tb, Tb, Tb, T0)
29
+
30
+ OPCODE(7, OP_GT_BII, "gt_bii", Tb, Ti, Ti, T0)
31
+ OPCODE(8, OP_GE_BII, "ge_bii", Tb, Ti, Ti, T0)
32
+ OPCODE(9, OP_EQ_BII, "eq_bii", Tb, Ti, Ti, T0)
33
+ OPCODE(10, OP_NE_BII, "ne_bii", Tb, Ti, Ti, T0)
34
+
35
+ OPCODE(11, OP_GT_BLL, "gt_bll", Tb, Tl, Tl, T0)
36
+ OPCODE(12, OP_GE_BLL, "ge_bll", Tb, Tl, Tl, T0)
37
+ OPCODE(13, OP_EQ_BLL, "eq_bll", Tb, Tl, Tl, T0)
38
+ OPCODE(14, OP_NE_BLL, "ne_bll", Tb, Tl, Tl, T0)
39
+
40
+ OPCODE(15, OP_GT_BFF, "gt_bff", Tb, Tf, Tf, T0)
41
+ OPCODE(16, OP_GE_BFF, "ge_bff", Tb, Tf, Tf, T0)
42
+ OPCODE(17, OP_EQ_BFF, "eq_bff", Tb, Tf, Tf, T0)
43
+ OPCODE(18, OP_NE_BFF, "ne_bff", Tb, Tf, Tf, T0)
44
+
45
+ OPCODE(19, OP_GT_BDD, "gt_bdd", Tb, Td, Td, T0)
46
+ OPCODE(20, OP_GE_BDD, "ge_bdd", Tb, Td, Td, T0)
47
+ OPCODE(21, OP_EQ_BDD, "eq_bdd", Tb, Td, Td, T0)
48
+ OPCODE(22, OP_NE_BDD, "ne_bdd", Tb, Td, Td, T0)
49
+
50
+ OPCODE(23, OP_GT_BSS, "gt_bss", Tb, Ts, Ts, T0)
51
+ OPCODE(24, OP_GE_BSS, "ge_bss", Tb, Ts, Ts, T0)
52
+ OPCODE(25, OP_EQ_BSS, "eq_bss", Tb, Ts, Ts, T0)
53
+ OPCODE(26, OP_NE_BSS, "ne_bss", Tb, Ts, Ts, T0)
54
+
55
+ OPCODE(27, OP_CAST_IB, "cast_ib", Ti, Tb, T0, T0)
56
+ OPCODE(28, OP_COPY_II, "copy_ii", Ti, Ti, T0, T0)
57
+ OPCODE(29, OP_ONES_LIKE_II, "ones_like_ii", Ti, T0, T0, T0)
58
+ OPCODE(30, OP_NEG_II, "neg_ii", Ti, Ti, T0, T0)
59
+ OPCODE(31, OP_ADD_III, "add_iii", Ti, Ti, Ti, T0)
60
+ OPCODE(32, OP_SUB_III, "sub_iii", Ti, Ti, Ti, T0)
61
+ OPCODE(33, OP_MUL_III, "mul_iii", Ti, Ti, Ti, T0)
62
+ OPCODE(34, OP_DIV_III, "div_iii", Ti, Ti, Ti, T0)
63
+ OPCODE(35, OP_POW_III, "pow_iii", Ti, Ti, Ti, T0)
64
+ OPCODE(36, OP_MOD_III, "mod_iii", Ti, Ti, Ti, T0)
65
+
66
+ OPCODE(37, OP_LSHIFT_III, "lshift_iii", Ti, Ti, Ti, T0)
67
+ OPCODE(38, OP_RSHIFT_III, "rshift_iii", Ti, Ti, Ti, T0)
68
+
69
+ OPCODE(39, OP_WHERE_IBII, "where_ibii", Ti, Tb, Ti, Ti)
70
+
71
+ OPCODE(40, OP_CAST_LI, "cast_li", Tl, Ti, T0, T0)
72
+ OPCODE(41, OP_COPY_LL, "copy_ll", Tl, Tl, T0, T0)
73
+ OPCODE(42, OP_ONES_LIKE_LL, "ones_like_ll", Tl, T0, T0, T0)
74
+ OPCODE(43, OP_NEG_LL, "neg_ll", Tl, Tl, T0, T0)
75
+ OPCODE(44, OP_ADD_LLL, "add_lll", Tl, Tl, Tl, T0)
76
+ OPCODE(45, OP_SUB_LLL, "sub_lll", Tl, Tl, Tl, T0)
77
+ OPCODE(46, OP_MUL_LLL, "mul_lll", Tl, Tl, Tl, T0)
78
+ OPCODE(47, OP_DIV_LLL, "div_lll", Tl, Tl, Tl, T0)
79
+ OPCODE(48, OP_POW_LLL, "pow_lll", Tl, Tl, Tl, T0)
80
+ OPCODE(49, OP_MOD_LLL, "mod_lll", Tl, Tl, Tl, T0)
81
+
82
+ OPCODE(50, OP_LSHIFT_LLL, "lshift_lll", Tl, Tl, Tl, T0)
83
+ OPCODE(51, OP_RSHIFT_LLL, "rshift_lll", Tl, Tl, Tl, T0)
84
+
85
+ OPCODE(52, OP_WHERE_LBLL, "where_lbll", Tl, Tb, Tl, Tl)
86
+
87
+ OPCODE(53, OP_CAST_FI, "cast_fi", Tf, Ti, T0, T0)
88
+ OPCODE(54, OP_CAST_FL, "cast_fl", Tf, Tl, T0, T0)
89
+ OPCODE(55, OP_COPY_FF, "copy_ff", Tf, Tf, T0, T0)
90
+ OPCODE(56, OP_ONES_LIKE_FF, "ones_like_ff", Tf, T0, T0, T0)
91
+ OPCODE(57, OP_NEG_FF, "neg_ff", Tf, Tf, T0, T0)
92
+ OPCODE(58, OP_ADD_FFF, "add_fff", Tf, Tf, Tf, T0)
93
+ OPCODE(59, OP_SUB_FFF, "sub_fff", Tf, Tf, Tf, T0)
94
+ OPCODE(60, OP_MUL_FFF, "mul_fff", Tf, Tf, Tf, T0)
95
+ OPCODE(61, OP_DIV_FFF, "div_fff", Tf, Tf, Tf, T0)
96
+ OPCODE(62, OP_POW_FFF, "pow_fff", Tf, Tf, Tf, T0)
97
+ OPCODE(63, OP_MOD_FFF, "mod_fff", Tf, Tf, Tf, T0)
98
+ OPCODE(64, OP_SQRT_FF, "sqrt_ff", Tf, Tf, T0, T0)
99
+ OPCODE(65, OP_WHERE_FBFF, "where_fbff", Tf, Tb, Tf, Tf)
100
+ OPCODE(66, OP_FUNC_FFN, "func_ffn", Tf, Tf, Tn, T0)
101
+ OPCODE(67, OP_FUNC_FFFN, "func_fffn", Tf, Tf, Tf, Tn)
102
+
103
+ OPCODE(68, OP_CAST_DI, "cast_di", Td, Ti, T0, T0)
104
+ OPCODE(69, OP_CAST_DL, "cast_dl", Td, Tl, T0, T0)
105
+ OPCODE(70, OP_CAST_DF, "cast_df", Td, Tf, T0, T0)
106
+ OPCODE(71, OP_COPY_DD, "copy_dd", Td, Td, T0, T0)
107
+ OPCODE(72, OP_ONES_LIKE_DD, "ones_like_dd", Td, T0, T0, T0)
108
+ OPCODE(73, OP_NEG_DD, "neg_dd", Td, Td, T0, T0)
109
+ OPCODE(74, OP_ADD_DDD, "add_ddd", Td, Td, Td, T0)
110
+ OPCODE(75, OP_SUB_DDD, "sub_ddd", Td, Td, Td, T0)
111
+ OPCODE(76, OP_MUL_DDD, "mul_ddd", Td, Td, Td, T0)
112
+ OPCODE(77, OP_DIV_DDD, "div_ddd", Td, Td, Td, T0)
113
+ OPCODE(78, OP_POW_DDD, "pow_ddd", Td, Td, Td, T0)
114
+ OPCODE(79, OP_MOD_DDD, "mod_ddd", Td, Td, Td, T0)
115
+ OPCODE(80, OP_SQRT_DD, "sqrt_dd", Td, Td, T0, T0)
116
+ OPCODE(81, OP_WHERE_DBDD, "where_dbdd", Td, Tb, Td, Td)
117
+ OPCODE(82, OP_FUNC_DDN, "func_ddn", Td, Td, Tn, T0)
118
+ OPCODE(83, OP_FUNC_DDDN, "func_dddn", Td, Td, Td, Tn)
119
+
120
+ OPCODE(84, OP_EQ_BCC, "eq_bcc", Tb, Tc, Tc, T0)
121
+ OPCODE(85, OP_NE_BCC, "ne_bcc", Tb, Tc, Tc, T0)
122
+
123
+ OPCODE(86, OP_CAST_CI, "cast_ci", Tc, Ti, T0, T0)
124
+ OPCODE(87, OP_CAST_CL, "cast_cl", Tc, Tl, T0, T0)
125
+ OPCODE(88, OP_CAST_CF, "cast_cf", Tc, Tf, T0, T0)
126
+ OPCODE(89, OP_CAST_CD, "cast_cd", Tc, Td, T0, T0)
127
+ OPCODE(90, OP_ONES_LIKE_CC, "ones_like_cc", Tc, T0, T0, T0)
128
+ OPCODE(91, OP_COPY_CC, "copy_cc", Tc, Tc, T0, T0)
129
+ OPCODE(92, OP_NEG_CC, "neg_cc", Tc, Tc, T0, T0)
130
+ OPCODE(93, OP_ADD_CCC, "add_ccc", Tc, Tc, Tc, T0)
131
+ OPCODE(94, OP_SUB_CCC, "sub_ccc", Tc, Tc, Tc, T0)
132
+ OPCODE(95, OP_MUL_CCC, "mul_ccc", Tc, Tc, Tc, T0)
133
+ OPCODE(96, OP_DIV_CCC, "div_ccc", Tc, Tc, Tc, T0)
134
+ OPCODE(97, OP_WHERE_CBCC, "where_cbcc", Tc, Tb, Tc, Tc)
135
+ OPCODE(98, OP_FUNC_CCN, "func_ccn", Tc, Tc, Tn, T0)
136
+ OPCODE(99, OP_FUNC_CCCN, "func_cccn", Tc, Tc, Tc, Tn)
137
+
138
+ OPCODE(100, OP_REAL_DC, "real_dc", Td, Tc, T0, T0)
139
+ OPCODE(101, OP_IMAG_DC, "imag_dc", Td, Tc, T0, T0)
140
+ OPCODE(102, OP_COMPLEX_CDD, "complex_cdd", Tc, Td, Td, T0)
141
+
142
+ OPCODE(103, OP_COPY_SS, "copy_ss", Ts, Ts, T0, T0)
143
+
144
+ OPCODE(104, OP_WHERE_BBBB, "where_bbbb", Tb, Tb, Tb, Tb)
145
+
146
+ OPCODE(105, OP_CONTAINS_BSS, "contains_bss", Tb, Ts, Ts, T0)
147
+
148
+ OPCODE(106, OP_REDUCTION, NULL, T0, T0, T0, T0)
149
+
150
+ /* Last argument in a reduction is the axis of the array the
151
+ reduction should be applied along. */
152
+
153
+ OPCODE(107, OP_SUM_IIN, "sum_iin", Ti, Ti, Tn, T0)
154
+ OPCODE(108, OP_SUM_LLN, "sum_lln", Tl, Tl, Tn, T0)
155
+ OPCODE(109, OP_SUM_FFN, "sum_ffn", Tf, Tf, Tn, T0)
156
+ OPCODE(110, OP_SUM_DDN, "sum_ddn", Td, Td, Tn, T0)
157
+ OPCODE(111, OP_SUM_CCN, "sum_ccn", Tc, Tc, Tn, T0)
158
+
159
+ OPCODE(112, OP_PROD, NULL, T0, T0, T0, T0)
160
+ OPCODE(113, OP_PROD_IIN, "prod_iin", Ti, Ti, Tn, T0)
161
+ OPCODE(114, OP_PROD_LLN, "prod_lln", Tl, Tl, Tn, T0)
162
+ OPCODE(115, OP_PROD_FFN, "prod_ffn", Tf, Tf, Tn, T0)
163
+ OPCODE(116, OP_PROD_DDN, "prod_ddn", Td, Td, Tn, T0)
164
+ OPCODE(117, OP_PROD_CCN, "prod_ccn", Tc, Tc, Tn, T0)
165
+
166
+ OPCODE(118, OP_MIN, NULL, T0, T0, T0, T0)
167
+ OPCODE(119, OP_MIN_IIN, "min_iin", Ti, Ti, Tn, T0)
168
+ OPCODE(120, OP_MIN_LLN, "min_lln", Tl, Tl, Tn, T0)
169
+ OPCODE(121, OP_MIN_FFN, "min_ffn", Tf, Tf, Tn, T0)
170
+ OPCODE(122, OP_MIN_DDN, "min_ddn", Td, Td, Tn, T0)
171
+
172
+ OPCODE(123, OP_MAX, NULL, T0, T0, T0, T0)
173
+ OPCODE(124, OP_MAX_IIN, "max_iin", Ti, Ti, Tn, T0)
174
+ OPCODE(125, OP_MAX_LLN, "max_lln", Tl, Tl, Tn, T0)
175
+ OPCODE(126, OP_MAX_FFN, "max_ffn", Tf, Tf, Tn, T0)
176
+ OPCODE(127, OP_MAX_DDN, "max_ddn", Td, Td, Tn, T0)
177
+
178
+ /* Should be the last opcode */
179
+ OPCODE(128, OP_END, NULL, T0, T0, T0, T0)