Example #1
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This allows to resolve the return type.
        """
        # Fold keyword arguments and resolve default values
        def normal_handler(index, param, value):
            return value
        def default_handler(index, param, default):
            return self.typeof_pyval(default)
        def stararg_handler(index, param, values):
            return types.Tuple(values)
        args = fold_arguments(self._pysig, args, kws,
                              normal_handler,
                              default_handler,
                              stararg_handler)
        kws = {}
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, args, kws
Example #2
0
def make_function_type(cffi_func):
    cffi_type = ffi.typeof(cffi_func)
    signature = map_type(cffi_type)
    cases = [signature]
    template = typing.make_concrete_template("CFFIFuncPtr", cffi_func, cases)
    result = types.FunctionPointer(template, get_pointer(cffi_func))
    return result
Example #3
0
def make_function_type(cffi_func):
    cffi_type = ffi.typeof(cffi_func)
    signature = map_type(cffi_type)
    cases = [signature]
    template = typing.make_concrete_template("CFFIFuncPtr", cffi_func, cases)
    result = types.FunctionPointer(template, get_pointer(cffi_func))
    return result
Example #4
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This allows to resolve the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        # XXX how about a dispatcher template class automating the
        # following?

        # Fold keyword arguments and resolve default values
        pysig, args = self._compiler.fold_argument_types(args, kws)
        kws = {}
        # Ensure an overload is available
        if self._can_compile:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, pysig, args, kws
Example #5
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given *args*
        and *kws*.  This allows to resolve the return type.
        """
        # Fold keyword arguments
        if kws:
            ba = self._pysig.bind(*args, **kws)
            if ba.kwargs:
                # There's a remaining keyword argument, e.g. if omitting
                # some argument with a default value before it.
                raise NotImplementedError("unhandled keyword argument: %s" %
                                          list(ba.kwargs))
            args = ba.args
            kws = {}
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, args, kws
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given *args*
        and *kws*.  This allows to resolve the return type.
        """
        # Fold keyword arguments
        if kws:
            ba = self._pysig.bind(*args, **kws)
            if ba.kwargs:
                # There's a remaining keyword argument, e.g. if omitting
                # some argument with a default value before it.
                raise NotImplementedError("unhandled keyword argument: %s" % list(ba.kwargs))
            args = ba.args
            kws = {}
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(name, key=func_name, signatures=self.nopython_signatures)
        return call_template, args, kws
Example #7
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This allows to resolve the return type.
        """

        # Fold keyword arguments and resolve default values
        def normal_handler(index, param, value):
            return value

        def default_handler(index, param, default):
            return self.typeof_pyval(default)

        def stararg_handler(index, param, values):
            return types.Tuple(values)

        args = fold_arguments(self._pysig, args, kws, normal_handler,
                              default_handler, stararg_handler)
        kws = {}
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, args, kws
Example #8
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This allows to resolve the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        # XXX how about a dispatcher template class automating the
        # following?

        # Fold keyword arguments and resolve default values
        pysig, args = self._compiler.fold_argument_types(args, kws)
        kws = {}
        # Ensure an overload is available
        if self._can_compile:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, pysig, args, kws
Example #9
0
    def test_scalar(self):
        flags = Flags()

        # Compile the inner function
        global cnd_jitted
        cr1 = compile_isolated(cnd, (types.float64,))
        cnd_jitted = cr1.entry_point
        # Manually type the compiled function for calling into
        tyctx = cr1.typing_context
        ctx = cr1.target_context
        signature = typing.make_concrete_template("cnd_jitted", cnd_jitted,
                                                  [cr1.signature])
        tyctx.insert_user_function(cnd_jitted, signature)

        # Compile the outer function
        array = types.Array(types.float64, 1, 'C')
        argtys = (array,) * 5 + (types.float64, types.float64)
        cr2 = compile_extra(tyctx, ctx, blackscholes_scalar_jitted,
                            args=argtys, return_type=None, flags=flags,
                            locals={})
        jitted_bs = cr2.entry_point

        OPT_N = 400
        iterations = 10

        callResultGold = np.zeros(OPT_N)
        putResultGold = np.zeros(OPT_N)

        callResultNumba = np.zeros(OPT_N)
        putResultNumba = np.zeros(OPT_N)

        stockPrice = randfloat(self.random.random_sample(OPT_N), 5.0, 30.0)
        optionStrike = randfloat(self.random.random_sample(OPT_N), 1.0, 100.0)
        optionYears = randfloat(self.random.random_sample(OPT_N), 0.25, 10.0)

        args = stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY

        ts = timer()
        for i in range(iterations):
             blackscholes_scalar(callResultGold, putResultGold, *args)
        te = timer()
        pytime = te - ts

        ts = timer()
        for i in range(iterations):
            jitted_bs(callResultNumba, putResultNumba, *args)
        te = timer()
        jittime = te - ts

        print("Python", pytime)
        print("Numba", jittime)
        print("Speedup: %s" % (pytime / jittime))

        delta = np.abs(callResultGold - callResultNumba)
        L1norm = delta.sum() / np.abs(callResultGold).sum()
        print("L1 norm: %E" % L1norm)
        print("Max absolute error: %E" % delta.max())
        self.assertAlmostEqual(delta.max(), 0)
Example #10
0
def make_function_type(cfnptr):
    cargs = [convert_ctypes(a)
             for a in cfnptr.argtypes]
    cret = convert_ctypes(cfnptr.restype)

    cases = [typing.signature(cret, *cargs)]
    template = typing.make_concrete_template("CFuncPtr", cfnptr, cases)

    pointer = ctypes.cast(cfnptr, ctypes.c_void_p).value
    return types.FunctionPointer(template, pointer)
Example #11
0
 def __init__(self, symbol, cstring):
     """Parse C function declaration/signature"""
     self.symbol = symbol
     parser = cffi.cparser.Parser()
     rft = parser.parse_type(cstring) # "RawFunctionType"
     self.restype = type_map[rft.result.build_backend_type(ffi, None)]
     self.argtypes = [type_map[arg.build_backend_type(ffi, None)] for arg in rft.args]
     signature = typing.signature(self.restype, *self.argtypes)
     cases = [signature]
     template = typing.make_concrete_template('ExternCFunction', self.symbol, cases)
     super(ExternCFunction, self).__init__(template)
Example #12
0
 def __init__(self, symbol, cstring):
     """Parse C function declaration/signature"""
     self.symbol = symbol
     parser = cffi.cparser.Parser()
     rft = parser.parse_type(cstring)  # "RawFunctionType"
     self.restype = type_map[rft.result.build_backend_type(ffi, None)]
     self.argtypes = [
         type_map[arg.build_backend_type(ffi, None)] for arg in rft.args
     ]
     signature = typing.signature(self.restype, *self.argtypes)
     cases = [signature]
     template = typing.make_concrete_template('ExternCFunction',
                                              self.symbol, cases)
     super(ExternCFunction, self).__init__(template)
Example #13
0
    def test_scalar(self):
        flags = Flags()

        # Compile the inner function
        global cnd_jitted
        cr1 = compile_isolated(cnd, (types.float64, ))
        cnd_jitted = cr1.entry_point
        # Manually type the compiled function for calling into
        tyctx = cr1.typing_context
        ctx = cr1.target_context
        signature = typing.make_concrete_template("cnd_jitted", cnd_jitted,
                                                  [cr1.signature])
        tyctx.insert_user_function(cnd_jitted, signature)

        # Compile the outer function
        array = types.Array(types.float64, 1, 'C')
        argtys = (array, ) * 5 + (types.float64, types.float64)
        cr2 = compile_extra(tyctx,
                            ctx,
                            blackscholes_scalar_jitted,
                            args=argtys,
                            return_type=None,
                            flags=flags,
                            locals={})
        jitted_bs = cr2.entry_point

        OPT_N = 400
        iterations = 10

        callResultGold = np.zeros(OPT_N)
        putResultGold = np.zeros(OPT_N)

        callResultNumba = np.zeros(OPT_N)
        putResultNumba = np.zeros(OPT_N)

        stockPrice = randfloat(self.random.random_sample(OPT_N), 5.0, 30.0)
        optionStrike = randfloat(self.random.random_sample(OPT_N), 1.0, 100.0)
        optionYears = randfloat(self.random.random_sample(OPT_N), 0.25, 10.0)

        args = stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY

        blackscholes_scalar(callResultGold, putResultGold, *args)
        jitted_bs(callResultNumba, putResultNumba, *args)

        delta = np.abs(callResultGold - callResultNumba)
        L1norm = delta.sum() / np.abs(callResultGold).sum()
        print("L1 norm: %E" % L1norm)
        print("Max absolute error: %E" % delta.max())
        self.assertAlmostEqual(delta.max(), 0)
Example #14
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given *args*
        and *kws*.  This allows to resolve the return type.
        """
        if kws:
            raise TypeError("kwargs not supported")
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template
Example #15
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given *args*
        and *kws*.  This allows to resolve the return type.
        """
        if kws:
            raise TypeError("kwargs not supported")
        # Ensure an overload is available, but avoid compiler re-entrance
        if self._can_compile and not self.is_compiling:
            self.compile(tuple(args))

        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template
Example #16
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This enables the resolving of the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        # Ensure an overload is available
        if self._can_compile:
            self.compile(tuple(args))

        pysig = None
        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, pysig, args, kws
Example #17
0
    def add_overload(self, cres):
        args = tuple(cres.signature.args)
        sig = [a._code for a in args]
        self._insert(sig, cres.entry_point, cres.objectmode, cres.interpmode)
        self.overloads[args] = cres.entry_point
        self._compileinfos[args] = cres

        # Add native function for correct typing the code generation
        target = cres.target_context
        cfunc = cres.entry_point
        if cfunc in target.native_funcs:
            target.dynamic_map_function(cfunc)
            # Create function type for typing
            func_name = cres.fndesc.mangled_name
            name = "CallTemplate(%s)" % cres.fndesc.mangled_name
            # The `key` isn't really used except for diagnosis here,
            # so avoid keeping a reference to `cfunc`.
            call_template = typing.make_concrete_template(
                name, key=func_name, signatures=[cres.signature])
            self._function_types[args] = call_template
Example #18
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This enables the resolving of the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        # Ensure an overload is available
        if self._can_compile:
            self.compile(tuple(args))

        pysig = None
        # Create function type for typing
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        # The `key` isn't really used except for diagnosis here,
        # so avoid keeping a reference to `cfunc`.
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=self.nopython_signatures)
        return call_template, pysig, args, kws
Example #19
0
    def add_overload(self, cres):
        args = tuple(cres.signature.args)
        sig = [a._code for a in args]
        self._insert(sig, cres.entry_point, cres.objectmode)
        self.overloads[args] = cres.entry_point
        self._compileinfos[args] = cres

        # Add native function for correct typing the code generation
        target = cres.target_context
        cfunc = cres.entry_point
        if cfunc in target.native_funcs:
            target.dynamic_map_function(cfunc)
            # Create function type for typing
            func_name = cres.fndesc.mangled_name
            name = "CallTemplate(%s)" % cres.fndesc.mangled_name
            # The `key` isn't really used except for diagnosis here,
            # so avoid keeping a reference to `cfunc`.
            call_template = typing.make_concrete_template(
                name, key=func_name, signatures=[cres.signature])
            self._function_types[args] = call_template
Example #20
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This enables the resolving of the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        assert not kws
        self._legalize_arg_types(args)
        # Coerce to object mode
        args = [types.ffi_forced_object] * len(args)

        if self._can_compile:
            self.compile(tuple(args))

        signatures = [typing.signature(self.output_types, *args)]
        pysig = None
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=signatures)

        return call_template, pysig, args, kws
Example #21
0
    def get_call_template(self, args, kws):
        """
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This enables the resolving of the return type.

        A (template, pysig, args, kws) tuple is returned.
        """
        assert not kws
        self._legalize_arg_types(args)
        # Coerce to object mode
        args = [types.ffi_forced_object] * len(args)

        if self._can_compile:
            self.compile(tuple(args))

        signatures = [typing.signature(self.output_types, *args)]
        pysig = None
        func_name = self.py_func.__name__
        name = "CallTemplate({0})".format(func_name)
        call_template = typing.make_concrete_template(
            name, key=func_name, signatures=signatures)

        return call_template, pysig, args, kws