Esempio n. 1
0
    def get_expr(self, block, rel):
        if self == ProfileOpType.INPUT_OUTPUT:
            return rel

        elif self == ProfileOpType.INTEG_INITIAL_COND:
            integ_expr = genoplib.unpack_integ(rel)
            return integ_expr.init_cond

        elif self == ProfileOpType.INTEG_DERIVATIVE_GAIN:
            integ_expr = genoplib.unpack_integ(rel)
            coeff, offset, exprs = genoplib.unpack_linear_operator(
                integ_expr.deriv)
            assert (all(map(lambda expr: expr.op == oplib.OpType.VAR, exprs)))
            all_vars = list(map(lambda e: e.name, exprs))

            block_vars = list(map(lambda inp: inp.name, block.inputs)) + \
                         list(map(lambda dat: dat.name, block.data))

            model_terms = list(filter(lambda v: not v in block_vars, all_vars))
            block_terms = list(filter(lambda v: v in block_vars, all_vars))
            rel = genoplib.product([genoplib.Const(coeff)] + \
                                   list(map(lambda v: genoplib.Var(v), \
                                            model_terms)))
            return rel
        elif self == ProfileOpType.INTEG_DERIVATIVE_BIAS:
            integ_expr = genoplib.unpack_integ(rel)
            coeff, offset, exprs = genoplib.unpack_linear_operator(
                integ_expr.deriv)
            return genoplib.Const(offset)
        else:
            return genoplib.Const(0.0)
Esempio n. 2
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)
Esempio n. 3
0
def get_calibration_objective_scores(all_models):
    #assert(models_are_homogenous(all_models,enable_outputs=False))
    block, loc, _, config = models_get_block_info(all_models, use_output=False)
    phys_models = {}
    models = {}

    for model in all_models:
        calib_obj = model.output.deltas[model.config.mode].objective
        if not model.hidden_cfg in phys_models:
            phys_models[model.hidden_cfg] = exp_phys_model_lib.ExpPhysModel(block, \
                                                                          config)
            models[model.hidden_cfg] = []

        phys_model = phys_models[model.hidden_cfg]
        models[model.hidden_cfg].append(model)

        for varname, val in model.variables().items():
            node = dectreelib.RegressionLeafNode(genoplib.Const(val))
            phys_model.set_variable(model.output, varname, node)

    for hidden_cfg, model in phys_models.items():
        variables = dict(map(lambda tup: (tup[0],tup[1].expr.compute()), \
                             model.variables().items()))
        print(variables)
        calib_expr = model.calib_obj()
        if not all(map(lambda v: v in variables, calib_expr.vars())):
            continue

        yield models[hidden_cfg], calib_expr.compute(variables)
Esempio n. 4
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
Esempio n. 5
0
def _prepare_minimize_model(variables,expr,params,bounds={}):
  n_inputs = len(variables)
  #if phys.model.complete:
  #  return False

  repl = {}
  dataset = [None]*n_inputs
  for idx,bound_var in enumerate(variables):
    repl[bound_var] = genoplib.Var("x[%d]" % idx)

  for par,value in params.items():
    repl[par] = genoplib.Const(value)

  bounds_arr = [(None,None)]*n_inputs
  for var,(lower,upper) in bounds.items():
    if not var in variables:
       continue
    idx = variables.index(var)
    bounds_arr[idx] = (lower,upper)

  conc_expr = expr.substitute(repl)
  _,pyexpr = lambdoplib.to_python(conc_expr)
  return {
    'expr':pyexpr,
    'bounds':bounds_arr,
    'variable_array':variables
  }
Esempio n. 6
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
Esempio n. 7
0
    def _concretize(self, expr):
        sub_dict = {}
        for var, val in self.get_digital_config():
            sub_dict[var] = genoplib.Const(val)

        for stmt in self.cfg.stmts:
            if stmt.type == adplib.ConfigStmtType.EXPR:
                sub_dict[stmt.name] = stmt.concrete_expr

        conc_expr = expr.substitute(sub_dict)
        return conc_expr
Esempio n. 8
0
    def fit(self):
        for (out, var), model in self.variables.items():
            codes, values = self.data.get_dataset(self.block.outputs[out], var)
            npts = len(values)
            if len(values) == 0:
                raise Exception(
                    "no data for fitting variable <%s> at output <%s>" %
                    (var, out))

            try:
                result = modelfitlib.fit_model(model.params, model.expr, {
                    'inputs': codes,
                    'meas_mean': values
                })
            except Exception as e:
                print(
                    "[WARN] failed to predict <%s> for output <%s> of block <%s>"
                    % (var, out, self.block.name))
                print("   %s.%s deltavar=%s expr=%s" %
                      (self.block.name, out, var, model.expr))
                print("   EXCEPTION=%s" % e)
                continue

            self.values[(out, var)] = {}
            for par in model.params:
                self.values[(out, var)][par] = result['params'][par]

            subst = dict(map(lambda tup: (tup[0],genoplib.Const(tup[1])), \
                             self.values[(out,var)].items()))
            conc_expr = model.expr.substitute(subst)
            self.concrete_variables[(out, var)] = conc_expr

            error = 0.0
            all_errors = []
            for idx in range(npts):
                pred = conc_expr.compute(
                    dict(
                        map(lambda hc: (hc, codes[hc][idx]),
                            self.data.hidden_codes)))
                all_errors.append(values[idx] - pred)
                error += (values[idx] - pred)**2

            self.errors[(out, var)] = math.sqrt(error) / npts
            print("%s.%s npts=%d deltavar=%s error=%s expr=%s" \
                       % (self.block.name,out,npts, var,self.errors[(out,var)], conc_expr))
            for idx, (v, e) in enumerate(zip(values, all_errors)):
                ci = dict(map(lambda c: (c, codes[c][idx]), codes.keys()))
                #print("   codes=%s value=%s error=%s" % (ci,v,e))

        for (out, var), model in self.variables.items():
            if not (out, var) in self.concrete_variables:
                raise Exception(
                    "could not infer parametres for <%s> in output <%s>" %
                    (var, out))
Esempio n. 9
0
def validate_model(model, expr, surf, dataset):
    variables = list(dataset.inputs.keys())
    inputs = dataset.inputs
    npts = len(dataset.meas_mean)
    deviations = []

    # the moutiplier is fine
    # "mult_0_3_2_0" -> okay
    # "integ_0_3_1_0" -> not okay
    ## "integ_0_3_2_0" -> okay
    '''
  if str(model.cfg.inst) == "integ_0_3_1_0":
    surf.zero()
  '''

    n_failures = 0
    for idx in range(npts):
        inps = {}
        for var, val in dataset.get_input(idx).items():
            inps[var] = genoplib.Const(val)
        expr_val = val = expr.substitute(inps).compute()
        dev_val = surf.get(
            dict(map(lambda tup: (tup[0], tup[1].value), inps.items())))
        val = expr_val + dev_val
        err = val - dataset.meas_mean[idx]
        if abs(err) > 1e-6:
            print("fail delta=%f dev=%f pred=%f meas=%f err=%f noise=%f"  \
                  % (expr_val, dev_val, val, \
                     dataset.meas_mean[idx], \
                     err, \
                dataset.meas_stdev[idx]))
            n_failures += 1

        deviations.append(val - expr_val)
        '''
    print("pred=%f pred2=%f meas=%f err=%f noise=%f"  \
          % (val, expr_val, \
             dataset.meas_mean[idx], \
             err, \
             dataset.meas_stdev[idx]))

    '''
    if n_failures > 0:
        print("[warn] model validation failed: %d/%d datapoints." %
              (n_failures, npts))
        #raise Exception("model validation failed: %d/%d datapoints." % (n_failures,npts))

    print("DEVIATION %s %s dev=%f +- %f" \
          % (model.cfg.inst, model.cfg.mode, \
             np.mean(deviations), np.std(deviations)))
Esempio n. 10
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
Esempio n. 11
0
    def _compute(self, expr, values):
        vdict = dict(values)
        for inp, blks in self.inputs.items():
            val = 0.0
            for blk in blks:
                val += blk.compute(values)

            port = self.block.inputs[inp]

            if self.enable_intervals:
                val = port.interval[self.cfg.mode].clip(val)

            vdict[inp] = val

        #print("")
        #print(self.cfg)

        if self.user_defined is None:
            vdict_sym = dict(map(lambda tup: (tup[0], \
                                              genoplib.Const(tup[1])),  \
                                vdict.items()))

            #print(expr)
            val = expr.substitute(vdict_sym).compute()
        else:
            input_port, inputs, outputs = self.user_defined
            inp_val = vdict[input_port]
            idx = util.nearest_value(inputs, inp_val, index=True)
            val = outputs[idx]

        #print(vdict)
        #print("orig-val: %f" % val)
        val += self.get_model_error(self.error_model, vdict)

        #print("err-val: %f" % val)
        port = self.block.outputs[self.port.name]
        if self.enable_intervals:
            val = port.interval[self.cfg.mode].clip(val)

        #print("clip-val: %f" % val)
        return val
Esempio n. 12
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
Esempio n. 13
0
def sympy_unify_const(pat_expr, targ_expr):
    assert (len(pat_expr.vars()) <= 1)
    assert (len(targ_expr.vars()) == 0)
    targ_syms = {}
    targ_symexpr = lambdoplib.to_sympy(targ_expr, targ_syms)
    pat_syms = dict(targ_syms)
    pat_symexpr = lambdoplib.to_sympy(pat_expr, pat_syms)
    symbols = list(targ_syms.values()) + list(pat_syms.values())
    try:
        result = sympy_solve(targ_symexpr - pat_symexpr, \
                             symbols,dict=True)
    except Exception as e:
        return False, None, None

    assign = result[0]
    if len(pat_expr.vars()) == 1:
        pat_var = pat_expr.vars()[0]
        const_val = genoplib.Const(assign[pat_syms[pat_var]])
        return True, genoplib.Var(pat_var), const_val
    else:
        print(assign)
        raise NotImplementedError
Esempio n. 14
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
Esempio n. 15
0
 def get_model(self, params):
     repls = dict(map(lambda tup: (tup[0],oplib.Const(tup[1])), \
                      params.items()))
     return self.relation.substitute(repls)
Esempio n. 16
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
Esempio n. 17
0
def Sqrt(a):
    return Pow(a, genop.Const(0.5))
Esempio n. 18
0
def Div(a, b):
    return genop.Mult(a, Pow(b, genop.Const(-1)))
Esempio n. 19
0
def from_sympy(symexpr, no_aliasing=False):
    if isinstance(symexpr, sympy.Function):
        if isinstance(symexpr, sympy.sin):
            e0 = from_sympy(symexpr.args[0], no_aliasing)
            return Sin(e0)

        elif symexpr.func.name == "integ":
            assert (len(symexpr.args) == 2)
            e1 = from_sympy(symexpr.args[0], no_aliasing)
            e2 = from_sympy(symexpr.args[1], no_aliasing)
            return genop.Integ(e1, e2)

        elif symexpr.func.name == "max":
            assert (len(symexpr.args) == 2)
            e1 = from_sympy(symexpr.args[0], no_aliasing)
            e2 = from_sympy(symexpr.args[1], no_aliasing)
            return Max(e1, e2)

        elif symexpr.func.name == "abs":
            e1 = from_sympy(symexpr.args[-1], no_aliasing)
            return Abs(e1)

        elif symexpr.func.name == "sgn":
            e1 = from_sympy(symexpr.args[-1], no_aliasing)
            return Sgn(e1)

        elif symexpr.func.name == "call":
            efn = from_sympy(symexpr.args[0], no_aliasing)
            args = list(map(lambda e : from_sympy(e,no_aliasing), \
                            symexpr.args[1:]))
            return genop.Call(args, efn)

        elif symexpr.func.name == "func":
            ebody = from_sympy(symexpr.args[-1], no_aliasing)
            pars = list(map(lambda e: from_sympy(e,no_aliasing).name, \
                            symexpr.args[:-1]))
            return Func(pars, ebody)

        elif symexpr.func.name == "extvar":
            e1 = from_sympy(symexpr.args[-1], no_aliasing)
            assert (isinstance(e1, genop.Var))
            return genop.ExtVar(e1.name)

        elif symexpr.func.name == "emit":
            e1 = from_sympy(symexpr.args[-1], no_aliasing)
            return genop.Emit(e1)

        elif symexpr.func.name == "map":
            raise FromSympyFailed("cannot convert mapping %s back to expr" %
                                  symexpr)

        else:
            raise Exception("unhandled func: %s" % (symexpr.func))

    elif isinstance(symexpr, sympy.Pow):
        e1 = from_sympy(symexpr.args[0], no_aliasing)
        e2 = from_sympy(symexpr.args[1], no_aliasing)
        return Pow(e1, e2)

    elif isinstance(symexpr, sympy.Symbol):
        if no_aliasing:
            name = symexpr.name.split(".")[0]
        else:
            name = symexpr.name

        return genop.Var(name)

    elif isinstance(symexpr, sympy.Float) or \
         isinstance(symexpr, sympy.Integer):
        return genop.Const(float(symexpr))

    elif isinstance(symexpr, sympy.Mul):
        args = list(map(lambda a: from_sympy(a,no_aliasing), \
                        symexpr.args))
        return genop.product(args)
    elif isinstance(symexpr, sympy.Add):
        args = list(map(lambda a: from_sympy(a,no_aliasing), \
                        symexpr.args))
        return genop.sum(args)
    elif isinstance(symexpr, sympy.Rational):
        return genop.Const(float(symexpr))
    else:
        print(symexpr.func)
        raise Exception(sympy.srepr(symexpr))