"""
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__) )
|