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
|
import os
import genapi
types = ['Generic','Number','Integer','SignedInteger','UnsignedInteger',
'Inexact',
'Floating', 'ComplexFloating', 'Flexible', 'Character',
'Byte','Short','Int', 'Long', 'LongLong', 'UByte', 'UShort',
'UInt', 'ULong', 'ULongLong', 'Float', 'Double', 'LongDouble',
'CFloat', 'CDouble', 'CLongDouble', 'Object', 'String', 'Unicode',
'Void']
h_template = r"""
#ifdef _MULTIARRAYMODULE
typedef struct {
PyObject_HEAD
npy_bool obval;
} PyBoolScalarObject;
static unsigned int PyArray_GetNDArrayCVersion (void);
static PyTypeObject PyBigArray_Type;
static PyTypeObject PyArray_Type;
static PyTypeObject PyArrayDescr_Type;
static PyTypeObject PyArrayFlags_Type;
static PyTypeObject PyArrayIter_Type;
static PyTypeObject PyArrayMapIter_Type;
static PyTypeObject PyArrayMultiIter_Type;
static int NPY_NUMUSERTYPES=0;
static PyTypeObject PyBoolArrType_Type;
static PyBoolScalarObject _PyArrayScalar_BoolValues[2];
%s
#else
#if defined(PY_ARRAY_UNIQUE_SYMBOL)
#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
#endif
#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
extern void **PyArray_API;
#else
#if defined(PY_ARRAY_UNIQUE_SYMBOL)
void **PyArray_API;
#else
static void **PyArray_API=NULL;
#endif
#endif
#define PyArray_GetNDArrayCVersion (*(unsigned int (*)(void)) PyArray_API[0])
#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
%s
#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
static int
_import_array(void)
{
PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
PyObject *c_api = NULL;
if (numpy == NULL) return -1;
c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
if (c_api == NULL) {Py_DECREF(numpy); return -1;}
if (PyCObject_Check(c_api)) {
PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
}
Py_DECREF(c_api);
Py_DECREF(numpy);
if (PyArray_API == NULL) return -1;
/* Perform runtime check of C API version */
if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
PyErr_Format(PyExc_RuntimeError, "module compiled against "\
"version %%x of C-API but this version of numpy is %%x", \
(int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
return -1;
}
return 0;
}
#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return; } }
#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
#endif
#endif
"""
c_template = r"""
/* These pointers will be stored in the C-object for use in other
extension modules
*/
void *PyArray_API[] = {
(void *) PyArray_GetNDArrayCVersion,
(void *) &PyBigArray_Type,
(void *) &PyArray_Type,
(void *) &PyArrayDescr_Type,
(void *) &PyArrayFlags_Type,
(void *) &PyArrayIter_Type,
(void *) &PyArrayMultiIter_Type,
(int *) &NPY_NUMUSERTYPES,
(void *) &PyBoolArrType_Type,
(void *) &_PyArrayScalar_BoolValues,
%s
};
"""
def generate_api(output_dir, force=False):
basename = 'multiarray_api'
h_file = os.path.join(output_dir, '__%s.h' % basename)
c_file = os.path.join(output_dir, '__%s.c' % basename)
d_file = os.path.join(output_dir, '%s.txt' % basename)
targets = (h_file, c_file, d_file)
sources = ['array_api_order.txt', 'multiarray_api_order.txt']
if (not force and not genapi.should_rebuild(targets, sources + [__file__])):
return targets
else:
do_generate_api(targets, sources)
return targets
def do_generate_api(targets, sources):
header_file = targets[0]
c_file = targets[1]
doc_file = targets[2]
objectapi_list = genapi.get_api_functions('OBJECT_API',
sources[0])
multiapi_list = genapi.get_api_functions('MULTIARRAY_API',
sources[1])
# API fixes for __arrayobject_api.h
fixed = 10
numtypes = len(types) + fixed
numobject = len(objectapi_list) + numtypes
nummulti = len(multiapi_list)
numtotal = numobject + nummulti
module_list = []
extension_list = []
init_list = []
# setup types
for k, atype in enumerate(types):
num = fixed + k
astr = " (void *) &Py%sArrType_Type," % types[k]
init_list.append(astr)
astr = "static PyTypeObject Py%sArrType_Type;" % types[k]
module_list.append(astr)
astr = "#define Py%sArrType_Type (*(PyTypeObject *)PyArray_API[%d])" % \
(types[k], num)
extension_list.append(astr)
# set up object API
genapi.add_api_list(numtypes, 'PyArray_API', objectapi_list,
module_list, extension_list, init_list)
# set up multiarray module API
genapi.add_api_list(numobject, 'PyArray_API', multiapi_list,
module_list, extension_list, init_list)
# Write to header
fid = open(header_file, 'w')
s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
fid.write(s)
fid.close()
# Write to c-code
fid = open(c_file, 'w')
s = c_template % '\n'.join(init_list)
fid.write(s)
fid.close()
# write to documentation
fid = open(doc_file, 'w')
fid.write('''
===========
Numpy C-API
===========
Object API
==========
''')
for func in objectapi_list:
fid.write(func.to_ReST())
fid.write('\n\n')
fid.write('''
Multiarray API
==============
''')
for func in multiapi_list:
fid.write(func.to_ReST())
fid.write('\n\n')
fid.close()
return targets
|