def test_run(self): from nitrous.module import jit_module, so_module from nitrous.function import function, c_function from nitrous.types import Float axpy = c_function("axpy", Float, [Float, Float, Float]) multiply = c_function("multiply", Float, [Float, Float]) @function(Float, a=Float, b=Float, c=Float) def foo(a, b, c): return axpy(a, b, c) + multiply(a, c) a, b, c = 11, 23, 7 ref = (a * b + c) + a * c jit_m = jit_module([foo], libs=[self.lib]) self.assertEqual(jit_m.foo(a, b, c), ref) so_m = so_module([foo], libs=[self.lib]) self.assertEqual(so_m.foo(a, b, c), ref)
def test_run(self): from nitrous.module import jit_module, so_module from nitrous.function import function, c_function from nitrous.types import Float axpy = c_function("axpy", Float, [Float, Float, Float]) multiply = c_function("multiply", Float, [Float, Float]) @function(Float, a=Float, b=Float, c=Float) def foo(a, b, c): return axpy(a, b, c) + multiply(a, c) a, b, c = 11, 23, 7 ref = (a * b + c) + a * c jit_m = jit_module([foo], libs=[self.lib]) self.assertEqual(jit_m.foo(a, b, c), ref) so_m = so_module([foo], libs=[self.lib]) self.assertEqual(so_m.foo(a, b, c), ref)
def print_(*args, **kwargs): """``print_(value, ..., end='\\n', file=sys.stdout)`` Also available through ``print`` built-in. Currently supports only several basic types, namely strings, integers of different widths, floats and doubles. *file* argument accepts only file objects with ``fileno()`` method. *sep* argument is currently unsupported. """ from nitrous.function import c_function, _get_or_create_function, emit_constant_string from nitrous.types import Int, Long, Double, String from sys import stdout # TODO add support for .sep parameter; this will require # to implement string joining or have one printf for every arg. # Move this somewhere, maybe `nitrous.lib.c`? dprintf = c_function("dprintf", Int, [Int, String]) def emit(builder): module = llvm.GetParentModule__(builder) llvm_printf, _ = _get_or_create_function(module, dprintf, vargs=True) cast_args = [] formats = [] # Getting file descriptor file_ = kwargs['file'] or stdout fileno = llvm.ConstInt(Int.llvm_type, file_.fileno(), True) # Performing certain casts for simplicity. for a in args: ty = llvm.TypeOf(a) if llvm.types_equal(ty, String.llvm_type): formats.append("%s") elif llvm.GetTypeKind(ty) == llvm.IntegerTypeKind: formats.append("%ld") a, _ = cast(a, Long).emit(builder) elif llvm.GetTypeKind(ty) == llvm.DoubleTypeKind: formats.append("%lf") elif llvm.GetTypeKind(ty) == llvm.FloatTypeKind: formats.append("%lf") # XXX for some reason floats are not printing. Looking # at Clang disassembly of printf("%f", (float)2.0), the # resulting constant type is double... Why? a, _ = cast(a, Double).emit(builder) else: raise TypeError("Unknown argument type") cast_args.append(a) # Appending end terminator, if any, else a newline. end = kwargs['end'] if end is None: end = emit_constant_string(builder, "\n") cast_args.append(end) # Creating final format string, args and making the call. format_ = emit_constant_string(builder, " ".join(formats) + "%s") args_ = (llvm.ValueRef * (len(cast_args) + 2))(fileno, format_, *cast_args) llvm.BuildCall(builder, llvm_printf, args_, len(args_), "print") return None, None return ValueEmitter(emit)
def print_(*args, **kwargs): """``print_(value, ..., end='\\n', file=sys.stdout)`` Also available through ``print`` built-in. Currently supports only several basic types, namely strings, integers of different widths, floats and doubles. *file* argument accepts only file objects with ``fileno()`` method. *sep* argument is currently unsupported. """ from nitrous.function import c_function, _get_or_create_function, emit_constant_string from nitrous.types import Int, Long, Double, String from sys import stdout # TODO add support for .sep parameter; this will require # to implement string joining or have one printf for every arg. # Move this somewhere, maybe `nitrous.lib.c`? dprintf = c_function("dprintf", Int, [Int, String]) def emit(builder): module = llvm.GetParentModule__(builder) llvm_printf, _ = _get_or_create_function(module, dprintf, vargs=True) cast_args = [] formats = [] # Getting file descriptor file_ = kwargs['file'] or stdout fileno = llvm.ConstInt(Int.llvm_type, file_.fileno(), True) # Performing certain casts for simplicity. for a in args: ty = llvm.TypeOf(a) if llvm.types_equal(ty, String.llvm_type): formats.append("%s") elif llvm.GetTypeKind(ty) == llvm.IntegerTypeKind: formats.append("%ld") a, _ = cast(a, Long).emit(builder) elif llvm.GetTypeKind(ty) == llvm.DoubleTypeKind: formats.append("%lf") elif llvm.GetTypeKind(ty) == llvm.FloatTypeKind: formats.append("%lf") # XXX for some reason floats are not printing. Looking # at Clang disassembly of printf("%f", (float)2.0), the # resulting constant type is double... Why? a, _ = cast(a, Double).emit(builder) else: raise TypeError("Unknown argument type") cast_args.append(a) # Appending end terminator, if any, else a newline. end = kwargs['end'] if end is None: end = emit_constant_string(builder, "\n") cast_args.append(end) # Creating final format string, args and making the call. format_ = emit_constant_string(builder, " ".join(formats) + "%s") args_ = (llvm.ValueRef * (len(cast_args) + 2))(fileno, format_, *cast_args) llvm.BuildCall(builder, llvm_printf, args_, len(args_), "print") return None, None return ValueEmitter(emit)