""" 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 """ from __future__ import absolute_import, print_function from . import base_info from . 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; const int _end = blitz::toEnd; blitz::Range _all = blitz::Range::all(); template static blitz::Array convert_to_blitz(PyArrayObject* arr_obj,const char* name) { blitz::TinyVector shape(0); blitz::TinyVector 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*) arr_obj->data,shape, return blitz::Array((T*) arr_obj->data,shape,strides, blitz::neverDeleteData); } template static blitz::Array py_to_blitz(PyArrayObject* arr_obj,const char* name) { blitz::TinyVector shape(0); blitz::TinyVector 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*) arr_obj->data,shape, return blitz::Array((T*) arr_obj->data,shape,strides, blitz::neverDeleteData); } """ local_dir,junk = os.path.split(os.path.abspath(__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"', '',''] 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 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__))