def visit_AllocArray(self, expr, boxed=False): if boxed: shape = self.tuple_to_stack_array(expr.shape) t = type_mappings.to_dtype(elt_type(expr.type)) return "(PyArrayObject*) PyArray_SimpleNew(%d, %s, %s)" % (expr.type.rank, shape, t) if config.debug: print "[Debug] Allocating array : %s " % expr.type return self.alloc_array(expr.type, expr.shape)
def box_scalar(self, x, t): if isinstance(t, BoolT): return "PyBool_FromLong(%s)" % x if x.replace("_", "").isalpha(): scalar = x else: scalar = self.fresh_name("scalar"); self.append("%s %s = %s;" % (self.to_ctype(t), scalar, x)) return "PyArray_Scalar(&%s, PyArray_DescrFromType(%s), NULL)" % (scalar, type_mappings.to_dtype(t) )
def visit_AllocArray(self, expr, boxed=False): if boxed: shape = self.tuple_to_stack_array(expr.shape) t = type_mappings.to_dtype(elt_type(expr.type)) return "(PyArrayObject*) PyArray_SimpleNew(%d, %s, %s)" % ( expr.type.rank, shape, t) if config.debug: print "[Debug] Allocating array : %s " % expr.type return self.alloc_array(expr.type, expr.shape)
def box_scalar(self, x, t): if isinstance(t, BoolT): return "PyBool_FromLong(%s)" % x if x.replace("_", "").isalpha(): scalar = x else: scalar = self.fresh_name("scalar") self.append("%s %s = %s;" % (self.to_ctype(t), scalar, x)) return "PyArray_Scalar(&%s, PyArray_DescrFromType(%s), NULL)" % ( scalar, type_mappings.to_dtype(t))
def make_boxed_array(self, elt_type, ndims, data_ptr, strides_array, shape_array, offset, size, base = "NULL"): # PyObject* PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data) typenum = type_mappings.to_dtype(elt_type) array_alloc = \ "(PyArrayObject*) PyArray_SimpleNewFromData(%d, %s, %s, &%s[%s])" % \ (ndims, shape_array, typenum, data_ptr, offset) vec = self.fresh_var("PyArrayObject*", "fresh_array", array_alloc) self.return_if_null(vec) # if the pointer had a PyObject reference, # set that as the new array's base if base not in ("0", "NULL"): self.append(""" if (%s) { %s->base = %s; Py_INCREF(%s); %s->flags &= ~NPY_ARRAY_OWNDATA; }""" % (base, vec, base, base, vec)) numpy_strides = self.fresh_var("npy_intp*", "numpy_strides") self.append("%s = PyArray_STRIDES( (PyArrayObject*) %s);" % (numpy_strides, vec)) bytes_per_elt = elt_type.dtype.itemsize for i in xrange(ndims): self.append("%s[%d] = %s[%d] * %d;" % (numpy_strides, i, strides_array, i, bytes_per_elt) ) self.append(""" // clear both fortran and c layout flags ((PyArrayObject*) %(vec)s)->flags &= ~NPY_F_CONTIGUOUS; ((PyArrayObject*) %(vec)s)->flags &= ~NPY_C_CONTIGUOUS; """ % locals()) f_layout_strides = ["1"] for i in xrange(1, ndims): shape_elt = "%s[%d]" % (shape_array, i) f_layout_strides.append(f_layout_strides[-1] + " * " + shape_elt) c_layout_strides = ["1"] for i in xrange(ndims-1,0,-1): shape_elt = "%s[%d]" % (shape_array, i) c_layout_strides = [c_layout_strides[-1] + " * " + shape_elt] + c_layout_strides strides_elts = ["%s[%d]" % (strides_array, i) for i in xrange(ndims)] is_c_layout = "&& ".join(self.eq(actual, ideal, Int64) for actual, ideal in zip(strides_elts, c_layout_strides)) is_f_layout = " && ".join(self.eq(actual, ideal, Int64) for actual, ideal in zip(strides_elts, f_layout_strides)) # make sure the contiguity flags are set correctly self.append(""" // it's possible that *neither* of the above flags should be on // which is why we enable them separately here if (%(is_f_layout)s) { ((PyArrayObject*)%(vec)s)->flags |= NPY_F_CONTIGUOUS; } if (%(is_c_layout)s) { ((PyArrayObject*)%(vec)s)->flags |= NPY_C_CONTIGUOUS; } """ % locals()) return vec
def make_boxed_array(self, elt_type, ndims, data_ptr, strides_array, shape_array, offset, size, base="NULL"): # PyObject* PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data) typenum = type_mappings.to_dtype(elt_type) array_alloc = \ "(PyArrayObject*) PyArray_SimpleNewFromData(%d, %s, %s, &%s[%s])" % \ (ndims, shape_array, typenum, data_ptr, offset) vec = self.fresh_var("PyArrayObject*", "fresh_array", array_alloc) self.return_if_null(vec) # if the pointer had a PyObject reference, # set that as the new array's base if base not in ("0", "NULL"): self.append(""" if (%s) { PyArray_SetBaseObject(%s, %s); Py_INCREF(%s); PyArray_CLEARFLAGS(%s, NPY_ARRAY_OWNDATA); }""" % (base, vec, base, base, vec)) numpy_strides = self.fresh_var("npy_intp*", "numpy_strides") self.append("%s = PyArray_STRIDES( (PyArrayObject*) %s);" % (numpy_strides, vec)) bytes_per_elt = elt_type.dtype.itemsize for i in xrange(ndims): self.append("%s[%d] = %s[%d] * %d;" % (numpy_strides, i, strides_array, i, bytes_per_elt)) self.append(""" // clear both fortran and c layout flags PyArray_CLEARFLAGS((PyArrayObject*) %(vec)s, NPY_ARRAY_F_CONTIGUOUS); PyArray_CLEARFLAGS((PyArrayObject*) %(vec)s, NPY_ARRAY_C_CONTIGUOUS); """ % locals()) f_layout_strides = ["1"] for i in xrange(1, ndims): shape_elt = "%s[%d]" % (shape_array, i) f_layout_strides.append(f_layout_strides[-1] + " * " + shape_elt) c_layout_strides = ["1"] for i in xrange(ndims - 1, 0, -1): shape_elt = "%s[%d]" % (shape_array, i) c_layout_strides = [c_layout_strides[-1] + " * " + shape_elt ] + c_layout_strides strides_elts = ["%s[%d]" % (strides_array, i) for i in xrange(ndims)] is_c_layout = "&& ".join( self.eq(actual, ideal, Int64) for actual, ideal in zip(strides_elts, c_layout_strides)) is_f_layout = " && ".join( self.eq(actual, ideal, Int64) for actual, ideal in zip(strides_elts, f_layout_strides)) # make sure the contiguity flags are set correctly self.append(""" // it's possible that *neither* of the above flags should be on // which is why we enable them separately here if (%(is_f_layout)s) { PyArray_ENABLEFLAGS((PyArrayObject*)%(vec)s, NPY_ARRAY_F_CONTIGUOUS); } if (%(is_c_layout)s) { PyArray_ENABLEFLAGS((PyArrayObject*)%(vec)s, NPY_ARRAY_C_CONTIGUOUS); } """ % locals()) return vec