Beispiel #1
0
def get_expr_coefficient(expr):
    if expr.op == baseoplib.OpType.INTEG:
        return 1.0, expr
    elif expr.op == baseoplib.OpType.MULT:
        c1, e1 = get_expr_coefficient(expr.arg(0))
        c2, e2 = get_expr_coefficient(expr.arg(1))
        if e1 is None and e2 is None:
            return c1 * c2, genoplib.Const(1.0)
        elif e1 is None:
            return c1 * c2, e2
        elif e2 is None:
            return c1 * c2, e1
        else:
            return c1 * c2, genoplib.Mult(e1, e2)
    elif expr.op == baseoplib.OpType.ADD:
        c1, _e1 = get_expr_coefficient(expr.arg(0))
        c2, _e2 = get_expr_coefficient(expr.arg(1))
        e1 = genoplib.Const(1) if _e1 is None else _e1
        e2 = genoplib.Const(1) if _e2 is None else _e2
        if c1 == c2:
            return c1, genoplib.Add(e1, e2)
        else:
            return c1, genoplib.Add(e1,
                                    genoplib.Mult(genoplib.Const(c2 / c1), e2))

    elif expr.op == baseoplib.OpType.CONST:
        return expr.value, None
    elif expr.op == baseoplib.OpType.VAR:
        return 1.0, expr
    elif expr.op == baseoplib.OpType.EMIT:
        c1, _e1 = get_expr_coefficient(expr.arg(0))
        return c1, genoplib.Emit(_e1, expr.loc)
    else:
        raise Exception("unhandled: %s" % expr)
Beispiel #2
0
def harmonize(baseline,deviations,modes):
    if harmonizable(baseline,deviations,modes):
        master_expr,gains_expr = \
                                 do_harmonize(baseline, \
                                              deviations, \
                                              modes)
        return master_expr,gains_expr

    if baseline.op == baseoplib.OpType.MULT and \
       match_op(baseoplib.OpType.MULT, deviations):
        master_expr1,gains_expr1 = \
            do_harmonize(baseline.arg(0), \
                     get_term(deviations,0),modes)
        master_expr2,gains_expr2 = \
            do_harmonize(baseline.arg(1), \
                     get_term(deviations,1),modes)
        gains_expr = gains_expr1 + gains_expr2
        return genoplib.Mult(master_expr1,master_expr2),gains_expr

    elif baseline.op == baseoplib.OpType.INTEG and \
         match_op(baseoplib.OpType.INTEG, deviations):
        master_expr1,gains_expr1 = \
            do_harmonize(baseline.arg(0), \
                     get_term(deviations,0),modes)
        master_expr2,gains_expr2 = \
            do_harmonize(baseline.arg(1), \
                     get_term(deviations,1),modes)
        gains_expr = gains_expr1 + gains_expr2
        return genoplib.Integ(master_expr1,master_expr2),gains_expr

    elif match_op(baseline.op, deviations):
        raise NotImplementedError

    else:
        raise NotHarmonizableError("cannot harmonize baseline and deviations")
Beispiel #3
0
def canonicalize_integration_operation(expr):
    has_integ_op = any(
        map(lambda n: n.op == baseoplib.OpType.INTEG, expr.nodes()))
    if has_integ_op:
        if expr.op == baseoplib.OpType.MULT:
            c, e = get_expr_coefficient(expr)
            if (e.op == baseoplib.OpType.INTEG):
                return genoplib.Integ(
                    genoplib.Mult(genoplib.Const(c), e.deriv),
                    genoplib.Mult(genoplib.Const(c), e.init_cond))
        elif expr.op == baseoplib.OpType.INTEG:
            return expr
        else:
            raise Exception("unhandled: %s" % expr)
    else:
        return expr
Beispiel #4
0
def apply_fuse_lut(goal,rule,unif):
  law_var = tablib.LawVar(rule.law,rule.ident,tablib.LawVar.APPLY)
  stmts = []
  if isinstance(goal.variable, tablib.DSVar):
    var_name = goal.variable.var
    stmts.append(tablib.VADPSource(law_var,genoplib.Var(var_name)))
  else:
    stmts.append(tablib.VADPConn(law_var,goal.variable))

  inpexpr = unif.get_by_name('a')
  coeff,base_expr = genoplib.factor_coefficient(inpexpr)
  assert(not base_expr is None)
  expr = unif.get_by_name('e')
  repl = {'T': genoplib.Mult(genoplib.Const(1.0/coeff),  \
                             genoplib.Var("y")) \
  }
  rule_var = vadplib.LawVar(rule.law,rule.ident)
  cfg = tablib.VADPConfig(rule_var,rule.mode)
  cfg.bind('e',expr.substitute(repl))
  stmts.append(cfg)

  

  new_unif = unifylib.Unification()
  new_unif.set_by_name('a', base_expr)

  return new_unif,stmts
Beispiel #5
0
    def mutate(self, p):
        def const_expr(p):
            len(p.vars()) == 0 or \
               all(map(lambda n: "par" in n, p.vars()))

        par_idx = len(self.get_params(p))
        if not const_expr(p) and \
            all(map(lambda n: isinstance(n,genoplib.Var), p.nodes())):
            yield genoplib.Mult(lamboplib.SmoothStep(p.copy()), p.copy())
Beispiel #6
0
    def root_functions(self):
        yield genoplib.Var('par0')

        for v in self.variables:
            yield genoplib.Mult(genoplib.Var('par0'), genoplib.Var(v))

        for v in self.variables:
            rng = self.ranges[v]
            middle = np.mean(rng)
            scale = max(abs(max(rng)), abs(min(rng)))
            norm = lamboplib.Normalize(genoplib.Var(v),
                                       offset=middle,
                                       ampl=scale)
Beispiel #7
0
def simplify_flip(dev,vadp_stmts,rule):
  sink_stmt = None
  for stmt in vadp_stmts:
    # identify a connection or source flip is used
    if isinstance(stmt, tablib.VADPConn) and \
       isinstance(stmt.source, tablib.LawVar) and \
       stmt.source.law == rule.law:
      sink_stmt = stmt
      sink_var = stmt.sink
      target_var = stmt.source
      break
    elif isinstance(stmt,tablib.VADPSource) and \
         isinstance(stmt.target, tablib.LawVar) and \
         stmt.target.law == rule.law:
      sink_stmt = stmt
      sink_var = VirtualSourceVar(stmt.dsexpr.name)
      target_var = stmt.port
      break

  # is there is no statement with rule variables
  if sink_stmt is None:
    return False,vadp_stmts

  # identify sink statement connected to law variable
  new_stmt = []
  replaced_stmts = [sink_stmt]
  for stmt in vadp_stmts:
    if isinstance(stmt,tablib.VADPSink) and \
       isinstance(stmt.port, tablib.LawVar) and \
       stmt.port.same_usage(target_var):
      new_stmt.append(tablib.VADPSink(sink_var, \
                               genoplib.Mult(genoplib.Const(-1), \
                                             stmt.dsexpr) \
      ))
      replaced_stmts.append(stmt)

  new_vadp = []
  for stmt in vadp_stmts:
    if not stmt in replaced_stmts:
      new_vadp.append(stmt)



  return True,new_vadp
Beispiel #8
0
def do_harmonize(baseline,deviations,modes):
    coeff,expr = genoplib \
                 .factor_positive_coefficient(baseline)
    new_gains = []
    new_modes = []
    gains = {}

    gain_var_name = gain_var(GAIN_ID)
    for mode,deviation in zip(modes,deviations):
        coeff_dev,expr_dev = genoplib \
                             .factor_positive_coefficient(deviation)
        if lambdaoplib.equivalent(expr,expr_dev):
            gain_value = coeff_dev/coeff
            gains[mode] = gain_value
        else:
            raise NotHarmonizableError("expressions not equal")

    master_expr = genoplib.Mult(genoplib.Var(gain_var_name),expr)
    return master_expr,[(gain_var_name,gains)]
Beispiel #9
0
def canonicalize_call(expr):
    call_expr = None
    if expr.op == oplib.OpType.MULT:
        args_const, args_exprs = separate(oplib.OpType.CONST,
                                          get_assoc(oplib.OpType.MULT, expr))
        const_val = 1.0
        for arg in args_const:
            const_val *= arg.value


        if len(args_exprs) == 1 and \
           args_exprs[0].op == oplib.OpType.CALL:
            call_expr = args_exprs[0]
            func_expr = call_expr.func
            new_impl = genoplib.Mult(genoplib.Const(const_val), \
                                     func_expr.expr)
            return genoplib.Call(call_expr.values, \
                                 lambdoplib.Func(func_expr.func_args, \
                                                 new_impl))
    else:
        return None
Beispiel #10
0
def render_config_info(board,graph,cfg):
    blk = board.get_block(cfg.inst.block)
    st = []
    st.append("\modes: %s" % (cfg.modes))
    for data in cfg.stmts_of_type(adplib \
                                  .ConfigStmtType \
                                  .CONSTANT):
        st.append("%s=%.2f scf=%.2e" % (data.name, \
                                        data.value, \
                                        data.scf))

    for data in cfg.stmts_of_type(adplib \
                                  .ConfigStmtType \
                                  .EXPR):
        inj_args = dict(map(lambda tup: (tup[0],  \
                                     genoplib.Mult(genoplib.Var(tup[0]), \
                                                   genoplib.Const(tup[1]))), \
                        data.injs.items()))
        subexpr = data.expr.substitute(inj_args)
        st.append("%s=%s injs=%s scfs=%s" \
                  % (data.name,data.expr,data.injs,data.scfs))

    ident = "%s-config" % cfg.inst
    graph.node(ident, "%s" % "\n".join(st), \
               shape="note", \
               style="filled", \
               fillcolor=Colors.LIGHTYELLOW)

    port_id = "%s:block" % (cfg.inst)
    graph.edge(ident,port_id, \
               penwidth="2", \
               style="dashed", \
               arrowhead="tee",
               arrowtail="normal", \
               color=Colors.ORANGE)
    return st
Beispiel #11
0
def compute_expression_fields(board,adp,cfg,compensate=True, debug=False):
    #print(cfg)
    blk = board.get_block(cfg.inst.block)

    if(len(blk.data) < 1):
        return

    data = list(filter(lambda d: d.type == blocklib.BlockDataType.EXPR, \
                        blk.data))

    if(len(data) < 1):
        return

    assert(len(data) == 1)
    # only allowed to have one output.
    output_port = blk.outputs.singleton()
    calib_obj = llenums.CalibrateObjective(adp.metadata[adplib.ADPMetadata.Keys.RUNTIME_CALIB_OBJ])

    rel = output_port.relation[cfg.mode]
    fn_call= util.singleton(filter(lambda n: n.op == oplib.OpType.CALL, rel.nodes()))
    fn_spec=fn_call.func
    fn_params = fn_call.values
    data_expr_field_name = util.singleton(fn_spec.expr.vars())
    data_expr_field = cfg.get(data_expr_field_name)

    # build offset map
    repls = {}
    for input_port, func_arg in zip(fn_call.values,fn_spec.func_args):
        if compensate:
            assert(input_port.op == oplib.OpType.VAR)
            conn = util.singleton(adp.incoming_conns(blk.name, cfg.inst.loc, input_port.name))
            src_block = board.get_block(conn.source_inst.block)
            src_cfg = adp.configs.get(conn.source_inst.block, conn.source_inst.loc)
            model = get_experimental_model(board, \
                                           src_block, \
                                           conn.source_inst.loc, \
                                           src_cfg, \
                                           calib_obj=calib_obj)
            gain,offset = get_compensation_parameters(model,init_cond=False)
        else:
            gain,offset = 1.0,0.0

        inj = data_expr_field.injs[func_arg]

        repls[func_arg] = genoplib.Mult(genoplib.Const(inj), \
                                        genoplib.Add( \
                                                      genoplib.Var(func_arg), \
                                                      genoplib.Const(-offset)
                                                     ))

        if debug:
            print("inp-var %s inj=%f offset=%f" % (func_arg,inj,offset))

    # compute model of output block
    if compensate:
        conn = util.singleton(adp.outgoing_conns(blk.name, cfg.inst.loc, output_port.name))
        dest_block = board.get_block(conn.dest_inst.block)
        dest_cfg = adp.configs.get(conn.dest_inst.block, conn.dest_inst.loc)

        model = get_experimental_model(board, \
                                       dest_block, \
                                       dest_cfg.inst.loc, \
                                       dest_cfg, \
                                       calib_obj=calib_obj)
        gain,offset = get_compensation_parameters(model,False)
    else:
        gain,offset = 1.0,0.0

    inj = data_expr_field.injs[data_expr_field.name]
    if debug:
        print("out-var %s inj=%f gain=%f offset=%f" % (data_expr_field.name, \
                                                    inj,gain,offset))

    func_impl = genoplib.Mult(genoplib.Const(inj), \
                              data_expr_field.expr.substitute(repls))
    if debug:
        print("func-expr: %s" % func_impl)

    rel_impl = genoplib.Add( \
                        rel.substitute({data_expr_field.name:func_impl}), \
                        genoplib.Const(-offset/gain) \
                       )
    output_port = blk.outputs.singleton()
    input_port = blk.inputs.singleton()
    final_expr = rel_impl.concretize()

    if debug:
        print("rel-expr: %s" % rel_impl)
        print("--- building lookup table ---")
        print(final_expr)

    input_values = input_port.quantize[cfg.mode] \
                             .get_values(input_port \
                                         .interval[cfg.mode])
    cfg[data_expr_field.name].set_input(input_port,input_values)

    lut_outs = []
    for val in input_values:
        out = final_expr.compute({input_port.name:val})
        out = max(min(1.0-1.0/128.0,out),-1.0)
        cfg[data_expr_field.name].set_output({input_port.name:val},out)

    cfg[data_expr_field.name].concrete_expr = final_expr
Beispiel #12
0
def Div(a, b):
    return genop.Mult(a, Pow(b, genop.Const(-1)))
Beispiel #13
0
def Square(a):
    return genop.Mult(a, a)