summaryrefslogtreecommitdiff
path: root/scipy/weave/blitz_spec.py
diff options
context:
space:
mode:
Diffstat (limited to 'scipy/weave/blitz_spec.py')
-rw-r--r--scipy/weave/blitz_spec.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/scipy/weave/blitz_spec.py b/scipy/weave/blitz_spec.py
new file mode 100644
index 000000000..2f0c97ba7
--- /dev/null
+++ b/scipy/weave/blitz_spec.py
@@ -0,0 +1,134 @@
+"""
+ 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
+from scipy.base import *
+from types import *
+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);
+ int stride_acc = 1;
+ //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);
+ int stride_acc = 1;
+ //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 os, 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"',
+ '"scipy/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__) )
+