def string_literal(self, string): """ Define a new string literal. """ from qy import Value if string not in self._literals: name = "literal%i" % len(self._literals) value = \ Value.from_low( llvm.GlobalVariable.new( self.module, llvm.Type.array(llvm.Type.int(8), len(string) + 1), name, ), ) value._value.linkage = llvm.LINKAGE_INTERNAL value._value.initializer = llvm.Constant.stringz(string) self._literals[string] = value return value else: return self._literals[string]
def value_from_any(self, value): """ Return a wrapping value. """ from qy import Value return Value.from_any(value)
def binomial_ll(parameter, sample): """ Return the likelihood of the model parameter under sample. """ # compile our method body from qy import ( Value, type_from_any, build_engine, ) q = \ Qy( return_type = type_from_any(float) , argument_types = [type_from_any(float)] * 3, default_return = Value.from_any(numpy.nan) , ) with q.active() as bar: q.return_(binomial_log_pdf(*q.main_body.argument_values)) engine = build_engine(q.module) # define the python wrapper from ctypes import ( CFUNCTYPE, c_double, ) prototype = CFUNCTYPE(c_double, c_double, c_double, c_double) generated = prototype(engine.get_pointer_to_function(q.main)) from qy.support import raise_if_set def wrapper(parameter, sample): """ Return the likelihood of the model parameter under sample. """ parameter = numpy.asarray(parameter, Binomial.parameter_dtype) result = generated(sample, parameter["p"], parameter["n"]) raise_if_set() return result # don't let the engine be GCed wrapper._engine = engine # replace and compute global binomial_ll binomial_ll = wrapper return binomial_ll(parameter, sample)
def stack_allocate(self, type_, initial = None, name = ""): """ Stack-allocate and return a value. """ from qy import Value allocated = Value.from_low(self.builder.alloca(self.type_from_any(type_), name)) if initial is not None: self.value_from_any(initial).store(allocated) return allocated
def decorator(emit_body): """ Emit the IR for a particular loop body. """ # prepare the loop structure builder = self.builder start = self.basic_block check = self.function.append_basic_block("for_loop_check") flesh = self.function.append_basic_block("for_loop_flesh") leave = self.function.append_basic_block("for_loop_leave") # build the check block builder.branch(check) builder.position_at_end(check) this_index = builder.phi(index_type, "for_loop_index") this_index.add_incoming(llvm.Constant.int(index_type, 0), start) builder.cbranch( builder.icmp( llvm.ICMP_UGT, count.low, this_index, ), flesh, leave, ) # build the flesh block from qy import Value builder.position_at_end(flesh) self._break_stack.append(leave) emit_body(Value.from_low(this_index)) self._break_stack.pop() this_index.add_incoming( builder.add(this_index, llvm.Constant.int(index_type, 1)), builder.basic_block, ) builder.branch(check) # wrap up the loop builder.position_at_end(leave)