Example #1
0
def datagear(func, **meta_kwds):
    if not is_standard_func(func):
        raise Exception(
            'Only regular functions can be converted to a @datagear.')

    paramspec = inspect.getfullargspec(func)

    invocation = ['*_data']

    for name in paramspec.kwonlyargs:
        invocation.append(f'{name}={name}')

    body = f'''async with gather({",".join(paramspec.args)}) as _data:
        yield datafunc({",".join(invocation)})'''

    execdict = {'datafunc': func, 'gather': gather}
    execdict.update(get_function_context_dict(func))

    gear_func = FunctionMaker.create(obj=func,
                                     body=body,
                                     evaldict=execdict,
                                     isasync=True,
                                     addsource=True)
    gear_func.exec = func

    return create_gear_definition(gear_func, hdl={'compile': True})
Example #2
0
    def __init__(self, gear):
        super().__init__()
        self.gear = gear
        self.functions: typing.Mapping[Function, FuncContext] = {}
        self.local_namespace = get_function_context_dict(self.gear.func).copy()

        paramspec = inspect.getfullargspec(self.gear.func)

        vararg = []
        for p in self.gear.in_ports:
            self.scope[p.basename] = ir.Variable(p.basename,
                                                 ir.IntfType[p.consumer.dtype],
                                                 val=p.consumer)

            if paramspec.varargs and p.basename.startswith(paramspec.varargs):
                vararg.append(self.ref(p.basename))

        if paramspec.varargs:
            self.local_namespace[paramspec.varargs] = ir.ConcatExpr(vararg)

        for p in self.gear.out_ports:
            self.scope[p.basename] = ir.Variable(p.basename,
                                                 ir.IntfType[p.consumer.dtype],
                                                 val=p.producer)

        for k, v in self.gear.explicit_params.items():
            self.scope[k] = ir.ResExpr(v)
Example #3
0
    def __init__(self, gear):
        super().__init__()
        self.gear = gear
        self.functions: typing.Mapping[Function, FuncContext] = {}
        self.local_namespace = get_function_context_dict(self.gear.func).copy()

        paramspec = inspect.getfullargspec(self.gear.func)

        # TODO: If local variable shadows output interface name, they will clash!!! (Example: dout)
        vararg = []
        for p in self.gear.in_ports:
            self.scope[p.basename] = ir.Variable(
                p.basename, ir.IntfType[p.dtype, ir.IntfType.iin])

            if paramspec.varargs and p.basename.startswith(paramspec.varargs):
                vararg.append(self.ref(p.basename))

        if paramspec.varargs:
            self.local_namespace[paramspec.varargs] = ir.ConcatExpr(vararg)

        for p in self.gear.out_ports:
            self.scope[p.basename] = ir.Variable(
                p.basename, ir.IntfType[p.consumer.dtype, ir.IntfType.iout])

        for k, v in self.gear.explicit_params.items():
            self.scope[k] = ir.ResExpr(v)
Example #4
0
def datagear(func, **meta_kwds):
    if not is_standard_func(func):
        raise Exception(
            'Only regular functions can be converted to a @datagear.')

    paramspec = inspect.getfullargspec(func)

    invocation = ['*_data']

    for name in paramspec.kwonlyargs:
        invocation.append(f'{name}={name}')

    body = f'''async with gather({",".join(paramspec.args)}) as _data:
        yield datafunc({",".join(invocation)})'''

    # TODO: Small optimization point to avoid async context manager. This needs to be supported by the compiler
    # invocation = [f'await {a}.pull()' for a in paramspec.args]
    # for name in paramspec.kwonlyargs:
    #     invocation.append(f'{name}={name}')

    # ack = ','.join(f'{a}.ack()' for a in paramspec.args)

    # body = f'''
    # yield datafunc({",".join(invocation)})
    # {ack}
    # '''

    execdict = {'datafunc': func, 'gather': gather}
    execdict.update(get_function_context_dict(func))

    gear_func = FunctionMaker.create(obj=func,
                                     body=body,
                                     evaldict=execdict,
                                     isasync=True,
                                     addsource=True)
    gear_func.exec = func

    return create_gear_definition(gear_func)
Example #5
0
def gear_base_resolver(func, *args, name=None, intfs=None, **kwds):
    meta_kwds = func.meta_kwds
    name = name or resolve_gear_name(func, meta_kwds['__base__'])

    err = None
    try:
        args, param_templates = gear_signature(func, args, kwds)

        param_templates['_enablement'] = meta_kwds['enablement']
        args, const_args = infer_const_args(args)
        check_args_specified(args)
    except (TooManyArguments, GearArgsNotSpecified) as e:
        err = type(e)(f'{str(e)}\n - when instantiating "{name}"')

    if err:
        raise err

    if intfs is None:
        fix_intfs = []
    elif isinstance(intfs, Intf):
        fix_intfs = [intfs]
    elif isinstance(intfs, dict):
        fix_intfs = intfs
    else:
        fix_intfs = list(intfs)

    if reg['gear/memoize']:
        gear_inst, outputs, memo_key = get_memoized_gear(
            func, args, const_args, kwds, fix_intfs, name)

        if gear_inst is not None:
            if len(outputs) == 1:
                return outputs[0]
            else:
                return outputs

    try:
        params = infer_params(args,
                              param_templates,
                              context=get_function_context_dict(func))
    except TypeMatchError as e:
        err = type(e)(f'{str(e)}\n - when instantiating "{name}"')

    if err:
        raise err

    if not err:
        if not params.pop('_enablement'):
            err = TypeMatchError(
                f'Enablement condition failed for "{name}" alternative'
                f' "{meta_kwds["definition"].__module__}.'
                f'{meta_kwds["definition"].__name__}": '
                f'{meta_kwds["enablement"].decode()}')

    params['name'] = name
    params['intfs'] = fix_intfs

    gear_inst = Gear(func, params)

    if err:
        err.gear = gear_inst
        err.root_gear = gear_inst

    if not err:
        gear_inst.connect_input(args, const_args)
        try:
            out_intfs, out_dtype = resolve_func(gear_inst)
            out_intfs = resolve_gear(gear_inst, out_intfs, out_dtype,
                                     fix_intfs)
            terminate_internal_intfs(gear_inst)

        except (TooManyArguments, GearTypeNotSpecified, GearArgsNotSpecified,
                TypeError, TypeMatchError, MultiAlternativeError) as e:
            err = e
            if hasattr(func, 'alternatives') or hasattr(
                    func, 'alternative_to'):
                err.root_gear = gear_inst
        except Exception as e:
            if not hasattr(e, '_stamped'):
                e.args = (
                    f'{str(e)}, in the module "{reg["gear/current_module"].name}/{name}"',
                )
                e._stamped = True

            err = e

    if err:
        if hasattr(func, 'alternatives') or hasattr(func, 'alternative_to'):
            gear_inst.parent.child.remove(gear_inst)
            for port in gear_inst.in_ports:
                if port.basename not in gear_inst.const_args:
                    port.producer.consumers.remove(port)
                else:
                    gear_inst.parent.child.remove(get_producer_port(port).gear)

        raise err

    if reg['gear/memoize'] and not func.__name__.endswith('_unpack__'):
        if memo_key is not None:
            memoize_gear(gear_inst, memo_key)

    return out_intfs
Example #6
0
    def __init__(self, funcref: Function, args, kwds):
        super().__init__()
        self.funcref = funcref

        func = funcref.func

        # self.name = funcref.name
        self.local_namespace = get_function_context_dict(func).copy()

        paramspec = inspect.getfullargspec(funcref.func)
        args = dict(zip(paramspec.args, args))
        args.update(kwds)

        self.ret_dtype = None
        self.const_args = {}

        if paramspec.defaults:
            for name, val in zip(reversed(paramspec.args), reversed(paramspec.defaults)):
                if name in args:
                    continue

                args[name] = ir.ResExpr(val)

        if func.__annotations__:
            kwddefaults = paramspec.kwonlydefaults or {}
            params = {**func.__annotations__, **kwddefaults}

            for a in paramspec.args:
                if a not in params:
                    params[a] = Any

            arg_types = {}
            for name in paramspec.args:
                if name not in args:
                    continue

                arg_types[name] = args[name].dtype

            for name, var in args.items():
                if name in params:
                    continue

                if isinstance(var, ir.ResExpr):
                    params[name] = var.val
                else:
                    params[name] = var

            res = infer_ftypes(params=params, args=arg_types, namespace=self.local_namespace)

            for name, dtype in res.items():
                if name == 'return':
                    continue

                if name not in args:
                    args[name] = ir.ResExpr(dtype)

                if isinstance(args[name], ir.ResExpr):
                    self.local_namespace[name] = args[name].val
                    self.const_args[name] = args[name]
                else:
                    self.scope[name] = ir.Variable(name, dtype)
        else:
            for name, arg in args.items():
                if isinstance(arg, ir.ResExpr):
                    self.local_namespace[name] = arg.val
                    self.const_args[name] = arg
                else:
                    self.scope[name] = ir.Variable(name, arg.dtype)

        self.signature = {
            name: var.dtype
            for name, var in args.items() if name not in self.const_args
        }