/
blitz_spec.py
129 lines (109 loc) · 4.63 KB
/
blitz_spec.py
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
"""
build_info holds classes that define the information
needed for building C++ extension modules for Python that
handle different data types. The information includes
such as include files, libraries, and even code snippets.
array_info -- for building functions that use scipy arrays
"""
import base_info
import standard_array_spec
import os
blitz_support_code = \
"""
// This should be declared only if they are used by some function
// to keep from generating needless warnings. for now, we'll always
// declare them.
int _beg = blitz::fromStart;
int _end = blitz::toEnd;
blitz::Range _all = blitz::Range::all();
template<class T, int N>
static blitz::Array<T,N> convert_to_blitz(PyArrayObject* arr_obj,const char* name)
{
blitz::TinyVector<int,N> shape(0);
blitz::TinyVector<int,N> strides(0);
//for (int i = N-1; i >=0; i--)
for (int i = 0; i < N; i++)
{
shape[i] = arr_obj->dimensions[i];
strides[i] = arr_obj->strides[i]/sizeof(T);
}
//return blitz::Array<T,N>((T*) arr_obj->data,shape,
return blitz::Array<T,N>((T*) arr_obj->data,shape,strides,
blitz::neverDeleteData);
}
template<class T, int N>
static blitz::Array<T,N> py_to_blitz(PyArrayObject* arr_obj,const char* name)
{
blitz::TinyVector<int,N> shape(0);
blitz::TinyVector<int,N> strides(0);
//for (int i = N-1; i >=0; i--)
for (int i = 0; i < N; i++)
{
shape[i] = arr_obj->dimensions[i];
strides[i] = arr_obj->strides[i]/sizeof(T);
}
//return blitz::Array<T,N>((T*) arr_obj->data,shape,
return blitz::Array<T,N>((T*) arr_obj->data,shape,strides,
blitz::neverDeleteData);
}
"""
import blitz_spec
local_dir,junk = os.path.split(os.path.abspath(blitz_spec.__file__))
blitz_dir = os.path.join(local_dir,'blitz')
# The need to warn about compilers made the info_object method in
# converters necessary and also this little class necessary.
# The spec/info unification needs to continue so that this can
# incorporated into the spec somehow.
class array_info(base_info.custom_info):
# throw error if trying to use msvc compiler
def check_compiler(self,compiler):
msvc_msg = 'Unfortunately, the blitz arrays used to support numeric' \
' arrays will not compile with MSVC.' \
' Please try using mingw32 (www.mingw.org).'
if compiler == 'msvc':
return ValueError, self.msvc_msg
class array_converter(standard_array_spec.array_converter):
def init_info(self):
standard_array_spec.array_converter.init_info(self)
blitz_headers = ['"blitz/array.h"',
'"numpy/arrayobject.h"',
'<complex>','<math.h>']
self.headers.extend(blitz_headers)
self.include_dirs = [blitz_dir]
self.support_code.append(blitz_support_code)
# type_name is used to setup the initial type conversion. Even
# for blitz conversion, the first step is to convert it to a
# standard numpy array.
#self.type_name = 'blitz'
self.type_name = 'numpy'
def info_object(self):
return array_info()
def type_spec(self,name,value):
new_spec = standard_array_spec.array_converter.type_spec(self,name,value)
new_spec.dims = len(value.shape)
if new_spec.dims > 11:
msg = "Error converting variable '" + name + "'. " \
"blitz only supports arrays up to 11 dimensions."
raise ValueError(msg)
return new_spec
def template_vars(self,inline=0):
res = standard_array_spec.array_converter.template_vars(self,inline)
if hasattr(self,'dims'):
res['dims'] = self.dims
return res
def declaration_code(self,templatize = 0,inline=0):
code = '%(py_var)s = %(var_lookup)s;\n' \
'%(c_type)s %(array_name)s = %(var_convert)s;\n' \
'conversion_numpy_check_type(%(array_name)s,%(num_typecode)s,"%(name)s");\n' \
'conversion_numpy_check_size(%(array_name)s,%(dims)s,"%(name)s");\n' \
'blitz::Array<%(num_type)s,%(dims)d> %(name)s =' \
' convert_to_blitz<%(num_type)s,%(dims)d>(%(array_name)s,"%(name)s");\n' \
'blitz::TinyVector<int,%(dims)d> N%(name)s = %(name)s.shape();\n'
code = code % self.template_vars(inline=inline)
return code
def __cmp__(self,other):
#only works for equal
return ( cmp(self.name,other.name) or
cmp(self.var_type,other.var_type) or
cmp(self.dims, other.dims) or
cmp(self.__class__, other.__class__) )