def implementation(target, code=None, namespace=None, dependencies=None, discard_units=None, name=None, **compiler_kwds):
    '\n    A simple decorator to extend user-written Python functions to work with code\n    generation in other languages.\n\n    Parameters\n    ----------\n    target : str\n        Name of the code generation target (e.g. ``\'cython\'``) for which to add\n        an implementation.\n    code : str or dict-like, optional\n        What kind of code the target language expects is language-specific,\n        e.g. C++ code allows for a dictionary of code blocks instead of a\n        single string.\n    namespaces : dict-like, optional\n        A namespace dictionary (i.e. a mapping of names to values) that\n        should be added to a `CodeObject` namespace when using this function.\n    dependencies : dict-like, optional\n        A mapping of names to `Function` objects, for additional functions\n        needed by this function.\n    discard_units: bool, optional\n        Numpy functions can internally make use of the unit system. However,\n        during a simulation run, state variables are passed around as unitless\n        values for efficiency. If `discard_units` is set to ``False``, input\n        arguments will have units added to them so that the function can still\n        use units internally (the units will be stripped away from the return\n        value as well). Alternatively, if `discard_units` is set to ``True``,\n        the function will receive unitless values as its input. The namespace\n        of the function will be altered to make references to units (e.g.\n        ``ms``) refer to the corresponding floating point values so that no\n        unit mismatch errors are raised. Note that this system cannot work in\n        all cases, e.g. it does not work with functions that internally imports\n        values (e.g. does ``from brian2 import ms``) or access values with\n        units indirectly (e.g. uses ``brian2.ms`` instead of ``ms``). If no\n        value is given, defaults to the preference setting\n        `codegen.runtime.numpy.discard_units`.\n    name : str, optional\n        The name of the function in the target language. Should only be\n        specified if the function has to be renamed for the target language.\n    compiler_kwds : dict, optional\n        Additional keyword arguments will be transferred to the code generation\n        stage, e.g. for C++-based targets, the code can make use of additional\n        header files by providing a list of strings as the ``headers`` argument.\n\n    Notes\n    -----\n    While it is in principle possible to provide a numpy implementation\n    as an argument for this decorator, this is normally not necessary -- the\n    numpy implementation should be provided in the decorated function.\n\n    If this decorator is used with other decorators such as `check_units` or\n    `declare_types`, it should be the uppermost decorator (that is, the\n    last one to be applied).\n\n    Examples\n    --------\n    Sample usage::\n\n        @implementation(\'cpp\',"""\n                    #include<math.h>\n                    inline double usersin(double x)\n                    {\n                        return sin(x);\n                    }\n                    """)\n        def usersin(x):\n            return sin(x)\n    '

    def do_user_implementation(func):
        if isinstance(func, Function):
            function = func
        else:
            function = Function(func)
        if discard_units:
            if (not ((target == 'numpy') and (code is None))):
                raise TypeError("'discard_units' can only be set for code generation target 'numpy', without providing any code.")
            function.implementations.add_numpy_implementation(wrapped_func=func, dependencies=dependencies, discard_units=discard_units, compiler_kwds=compiler_kwds)
        else:
            function.implementations.add_implementation(target, code=code, dependencies=dependencies, namespace=namespace, name=name, compiler_kwds=compiler_kwds)
        return function
    return do_user_implementation
A simple decorator to extend user-written Python functions to work with code
generation in other languages.

Parameters
----------
target : str
    Name of the code generation target (e.g. ``'cython'``) for which to add
    an implementation.
code : str or dict-like, optional
    What kind of code the target language expects is language-specific,
    e.g. C++ code allows for a dictionary of code blocks instead of a
    single string.
namespaces : dict-like, optional
    A namespace dictionary (i.e. a mapping of names to values) that
    should be added to a `CodeObject` namespace when using this function.
dependencies : dict-like, optional
    A mapping of names to `Function` objects, for additional functions
    needed by this function.
discard_units: bool, optional
    Numpy functions can internally make use of the unit system. However,
    during a simulation run, state variables are passed around as unitless
    values for efficiency. If `discard_units` is set to ``False``, input
    arguments will have units added to them so that the function can still
    use units internally (the units will be stripped away from the return
    value as well). Alternatively, if `discard_units` is set to ``True``,
    the function will receive unitless values as its input. The namespace
    of the function will be altered to make references to units (e.g.
    ``ms``) refer to the corresponding floating point values so that no
    unit mismatch errors are raised. Note that this system cannot work in
    all cases, e.g. it does not work with functions that internally imports
    values (e.g. does ``from brian2 import ms``) or access values with
    units indirectly (e.g. uses ``brian2.ms`` instead of ``ms``). If no
    value is given, defaults to the preference setting
    `codegen.runtime.numpy.discard_units`.
name : str, optional
    The name of the function in the target language. Should only be
    specified if the function has to be renamed for the target language.
compiler_kwds : dict, optional
    Additional keyword arguments will be transferred to the code generation
    stage, e.g. for C++-based targets, the code can make use of additional
    header files by providing a list of strings as the ``headers`` argument.

Notes
-----
While it is in principle possible to provide a numpy implementation
as an argument for this decorator, this is normally not necessary -- the
numpy implementation should be provided in the decorated function.

If this decorator is used with other decorators such as `check_units` or
`declare_types`, it should be the uppermost decorator (that is, the
last one to be applied).

Examples
--------
Sample usage::

    @implementation('cpp',"""
                #include<math.h>
                inline double usersin(double x)
                {
                    return sin(x);
                }
                """)
    def usersin(x):
        return sin(x)
def implementation(target, code=None, namespace=None, dependencies=None, discard_units=None, name=None, **compiler_kwds):
    '\n    A simple decorator to extend user-written Python functions to work with code\n    generation in other languages.\n\n    Parameters\n    ----------\n    target : str\n        Name of the code generation target (e.g. ``\'cython\'``) for which to add\n        an implementation.\n    code : str or dict-like, optional\n        What kind of code the target language expects is language-specific,\n        e.g. C++ code allows for a dictionary of code blocks instead of a\n        single string.\n    namespaces : dict-like, optional\n        A namespace dictionary (i.e. a mapping of names to values) that\n        should be added to a `CodeObject` namespace when using this function.\n    dependencies : dict-like, optional\n        A mapping of names to `Function` objects, for additional functions\n        needed by this function.\n    discard_units: bool, optional\n        Numpy functions can internally make use of the unit system. However,\n        during a simulation run, state variables are passed around as unitless\n        values for efficiency. If `discard_units` is set to ``False``, input\n        arguments will have units added to them so that the function can still\n        use units internally (the units will be stripped away from the return\n        value as well). Alternatively, if `discard_units` is set to ``True``,\n        the function will receive unitless values as its input. The namespace\n        of the function will be altered to make references to units (e.g.\n        ``ms``) refer to the corresponding floating point values so that no\n        unit mismatch errors are raised. Note that this system cannot work in\n        all cases, e.g. it does not work with functions that internally imports\n        values (e.g. does ``from brian2 import ms``) or access values with\n        units indirectly (e.g. uses ``brian2.ms`` instead of ``ms``). If no\n        value is given, defaults to the preference setting\n        `codegen.runtime.numpy.discard_units`.\n    name : str, optional\n        The name of the function in the target language. Should only be\n        specified if the function has to be renamed for the target language.\n    compiler_kwds : dict, optional\n        Additional keyword arguments will be transferred to the code generation\n        stage, e.g. for C++-based targets, the code can make use of additional\n        header files by providing a list of strings as the ``headers`` argument.\n\n    Notes\n    -----\n    While it is in principle possible to provide a numpy implementation\n    as an argument for this decorator, this is normally not necessary -- the\n    numpy implementation should be provided in the decorated function.\n\n    If this decorator is used with other decorators such as `check_units` or\n    `declare_types`, it should be the uppermost decorator (that is, the\n    last one to be applied).\n\n    Examples\n    --------\n    Sample usage::\n\n        @implementation(\'cpp\',"\n                    #include<math.h>\n                    inline double usersin(double x)\n                    {\n                        return sin(x);\n                    }\n                    ")\n        def usersin(x):\n            return sin(x)\n    '

    def do_user_implementation(func):
        if isinstance(func, Function):
            function = func
        else:
            function = Function(func)
        if discard_units:
            if (not ((target == 'numpy') and (code is None))):
                raise TypeError("'discard_units' can only be set for code generation target 'numpy', without providing any code.")
            function.implementations.add_numpy_implementation(wrapped_func=func, dependencies=dependencies, discard_units=discard_units, compiler_kwds=compiler_kwds)
        else:
            function.implementations.add_implementation(target, code=code, dependencies=dependencies, namespace=namespace, name=name, compiler_kwds=compiler_kwds)
        return function
    return do_user_implementation