def get_strided_type(element_type, shape, strides): """ Build an LLVM type to represent a strided array's structure. """ if shape: (inner_type, inner_size) = get_strided_type(element_type, shape[1:], strides[1:]) if strides[0] == 0: return (inner_type, inner_size) else: if strides[0] < inner_size: raise ValueError("array stride too small") else: return ( llvm.Type.array( llvm.Type.packed_struct([ inner_type, llvm.Type.array(llvm.Type.int(8), strides[0] - inner_size), ]), shape[0], ), shape[0] * strides[0], ) else: from qy import size_of_type return (element_type, size_of_type(element_type))
def from_raw(data, shape, strides = None): """ Build an array from a typical data pointer. @param data : Pointer value (with element-pointer type) to array data. @param shape : Tuple of dimension sizes (Python integers). @param strides : Tuple of dimension strides (Python integers). """ shape = map(int, shape) if strides is None: from qy import size_of_type strides = [] axis_size = size_of_type(data.type_.pointee) for d in reversed(shape): strides += [axis_size] axis_size *= d strides = list(reversed(strides)) else: strides = map(int, strides) (strided_type, _) = get_strided_type(data.type_.pointee, shape, strides) strided_data = data.cast_to(llvm.Type.pointer(strided_type)) return StridedArray(strided_data, shape, strides, data.type_.pointee)
def heap_allocate(self, type_, count = 1): """ Heap-allocate and return a value. """ # emit the allocation from qy import size_of_type type_ = self.type_from_any(type_) malloc = qy.Function.named("malloc", llvm.Type.pointer(llvm.Type.int(8)), [long]) bytes_ = (self.value_from_any(count) * size_of_type(type_)).cast_to(long) return malloc(bytes_).cast_to(llvm.Type.pointer(type_))