def make_approximation_f(name, approx_perc, approx_abs, approx_abs_S, max_value, max_value_S, ndp): F = ndp.get_ftype(name) ndp_before = get_approx_dp(F, name, approx_perc, approx_abs, approx_abs_S, max_value, max_value_S) name2ndp = {NAME_ORIGINAL: ndp, NAME_APPROX: ndp_before} fnames = ndp.get_fnames() rnames = ndp.get_rnames() connections = [] connections.append(Connection(NAME_APPROX, name, NAME_ORIGINAL, name)) for fn in fnames: F = ndp.get_ftype(fn) fn_ndp = dpwrap(Identity(F), fn, fn) fn_name = get_name_for_fun_node(fn) name2ndp[fn_name] = fn_ndp if fn == name: connections.append(Connection(fn_name, fn, NAME_APPROX, fn)) else: connections.append(Connection(fn_name, fn, NAME_ORIGINAL, fn)) for rn in rnames: R = ndp.get_rtype(rn) rn_ndp = dpwrap(Identity(R), rn, rn) rn_name = get_name_for_res_node(rn) name2ndp[rn_name] = rn_ndp connections.append(Connection(NAME_ORIGINAL, rn, rn_name, rn)) return CompositeNamedDP.from_parts(name2ndp, connections, fnames, rnames)
def eval_rvalue_VariableRef(rvalue, context): if rvalue.name in context.constants: c = context.constants[rvalue.name] assert isinstance(c, ValueWithUnits) return get_valuewithunits_as_resource(c, context) # return eval_rvalue(context.constants[rvalue.name], context) elif rvalue.name in context.var2resource: return context.var2resource[rvalue.name] try: dummy_ndp = context.get_ndp_fun(rvalue.name) except ValueError: # as e: msg = 'Function %r not declared.' % rvalue.name if context.fnames: msg += ' Available: %s.' % ", ".join(context.fnames) else: msg += ' No function declared so far.' raise DPSemanticError(msg, where=rvalue.where) s = dummy_ndp.get_rnames()[0] msg = ('Please use the more precise form "provided %s" rather than simply "%s".' % (rvalue.name, rvalue.name)) warn_language(rvalue, MCDPWarnings.LANGUAGE_REFERENCE_OK_BUT_IMPRECISE, msg, context) return context.make_resource(get_name_for_fun_node(rvalue.name), s)
def add_function(fname, F, context, r): check_isinstance(fname, str) if fname in context.fnames: msg = 'Repeated function name %r.' % fname raise DPSemanticError(msg, where=r.where) context.add_ndp_fun_node(fname, F) return context.make_resource(get_name_for_fun_node(fname), fname)
def get_new_name(name2): isf, fname = is_fun_node_name(name2) isr, rname = is_res_node_name(name2) if isf: return get_name_for_fun_node('%s%s%s' % (prefix, sep, fname)) elif isr: return get_name_for_res_node('%s%s%s' % (prefix, sep, rname)) else: return "%s%s%s" % (prefix, sep, name2)
def cndp_create_one_without_some_connections(ndp, exclude_connections, names): """ Creates a new CompositeNDP without some of the connections. A new function / resource pair is created for each cut connection. """ from mocdp.comp.context import Context context = Context() # Create the fun/res node in the original order for fname in ndp.get_fnames(): # simply copy the functionnode - it might be a LabeledNDP name = get_name_for_fun_node(fname) fndp = ndp.get_name2ndp()[name] context.fnames.append(fname) context.add_ndp(name, fndp) for rname in ndp.get_rnames(): # simply copy the functionnode - it might be a LabeledNDP name = get_name_for_res_node(rname) rndp = ndp.get_name2ndp()[name] context.rnames.append(rname) context.add_ndp(name, rndp) for _name, _ndp in ndp.get_name2ndp().items(): isf, fname = is_fun_node_name(_name) isr, rname = is_res_node_name(_name) if isf and fname in ndp.get_fnames(): pass elif isr and rname in ndp.get_rnames(): pass else: # print('regular: %r' % _name) context.add_ndp(_name, _ndp) for c in ndp.get_connections(): if c in exclude_connections: continue # print('adding connection %s' % str(c)) context.connections.append(c) # print('done') # for each cut connection for e, name in zip(exclude_connections, names): S = context.get_rtype(CResource(e.dp1, e.s1)) fn = context.add_ndp_fun_node(name, S) rn = context.add_ndp_res_node(name, S) c1 = Connection(e.dp1, e.s1, rn, name) c2 = Connection(fn, name, e.dp2, e.s2) context.connections.append(c1) context.connections.append(c2) return CompositeNamedDP.from_context(context)
def get_fname_label(self, ndp_name, fname): try: ndp = self.get_ndp(ndp_name) except DPInternalError as e: msg = 'get_fname_label(%s,%s) failed' % (ndp_name, fname) raise_wrapped(DPInternalError, e, msg, compact=True) if isinstance(ndp, CompositeNamedDP): child = get_name_for_fun_node(fname) return self.get_fname_label(ndp_name + (child, ), fname) if isinstance(ndp, NamedDPCoproduct): imp = get_value_from_impdict(self.imp_dict, ndp_name) assert isinstance(imp, dict) and len(imp) == 1, imp which = list(imp)[0] return self.get_fname_label(ndp_name + (which, ), fname) try: ndp, (lf, _) = self._evaluate(ndp_name) except ValueMissing: if isinstance(ndp, SimpleWrap) and isinstance( ndp.dp, (Mux, IdentityDP)): # Muxes and identities could be optimized away and disappear print( 'get_fname_label: Ignoring %s / %s because could be optimized away' % (ndp_name, fname)) return self.VALUE_FOR_MISSING else: raise # logger.error(e) # return self.VALUE_FOR_MISSING except DPInternalError as e: msg = 'Could not get %r fname %r' % (ndp_name, fname) raise_wrapped(DPInternalError, e, msg) fnames = ndp.get_fnames() assert fname in fnames if len(fnames) > 1: i = fnames.index(fname) lf = lowerset_project(lf, i) assert isinstance(lf, LowerSet) if len(lf.maximals) == 1: one = list(lf.maximals)[0] return lf.P.format(one) return lf.__str__()
def eval_rvalue_NewFunction(rvalue, context): check_isinstance(rvalue, CDP.NewFunction) check_isinstance(rvalue.name, CDP.FName) fname = rvalue.name.value try: dummy_ndp = context.get_ndp_fun(fname) except ValueError: msg = 'New resource name %r not declared.' % fname if context.rnames: msg += ' Available: %s.' % ", ".join(context.rnames) else: msg += ' No resources declared so far.' raise DPSemanticError(msg, where=rvalue.where) return context.make_resource(get_name_for_fun_node(fname), dummy_ndp.get_rnames()[0])
def get_fname_label(self, ndp_name, fname): try: ndp = self.get_ndp(ndp_name) except DPInternalError as e: msg = 'get_fname_label(%s,%s) failed' % (ndp_name, fname) raise_wrapped(DPInternalError, e, msg, compact=True) if isinstance(ndp, CompositeNamedDP): child = get_name_for_fun_node(fname) return self.get_fname_label(ndp_name + (child,), fname) if isinstance(ndp, NamedDPCoproduct): imp = get_value_from_impdict(self.imp_dict, ndp_name) assert isinstance(imp, dict) and len(imp) == 1, imp which = list(imp)[0] return self.get_fname_label(ndp_name + (which,), fname) try: ndp, (lf, _) = self._evaluate(ndp_name) except ValueMissing: if isinstance(ndp, SimpleWrap) and isinstance(ndp.dp, (Mux, IdentityDP)): # Muxes and identities could be optimized away and disappear print('get_fname_label: Ignoring %s / %s because could be optimized away' % (ndp_name, fname)) return self.VALUE_FOR_MISSING else: raise # logger.error(e) # return self.VALUE_FOR_MISSING except DPInternalError as e: msg = 'Could not get %r fname %r' % (ndp_name, fname) raise_wrapped(DPInternalError, e, msg) fnames = ndp.get_fnames() assert fname in fnames if len(fnames) > 1: i = fnames.index(fname) lf = lowerset_project(lf, i) assert isinstance(lf, LowerSet) if len(lf.maximals) == 1: one = list(lf.maximals)[0] return lf.P.format(one) return lf.__str__()
def add_function(fname, F, context, r, repeated_ok=False): check_isinstance(fname, str) try: check_good_name_for_function(fname) except ValueError as e: msg = 'Invalid name for functionality: %s' % e raise DPSemanticError(msg, where=r.where) if fname in context.fnames: if not repeated_ok: msg = 'Repeated function name %r.' % fname raise DPSemanticError(msg, where=r.where) else: # check same or different warnings.warn('check same') else: context.add_ndp_fun_node(fname, F) return context.make_resource(get_name_for_fun_node(fname), fname)
def connect_functions_to_outside(name2ndp, connections, ndp_name, fnames): """ For each function in fnames of ndp_name, create a new outside function node and connect it to ndp_name. """ assert ndp_name in name2ndp ndp = name2ndp[ndp_name] if not set(fnames).issubset(ndp.get_fnames()): msg = 'Some of the functions are not present.' raise_desc(ValueError, msg, fnames=fnames, ndp=ndp) for fname in fnames: F = ndp.get_ftype(fname) nn = get_name_for_fun_node(fname) name2ndp[nn] = dpwrap(Identity(F), fname, fname) connections.append(Connection(nn, fname, ndp_name, fname))
def connect_functions_to_outside(name2ndp, connections, ndp_name, fnames): """ For each function in fnames of ndp_name, create a new outside function node and connect it to ndp_name. """ assert ndp_name in name2ndp ndp = name2ndp[ndp_name] if not set(fnames).issubset(ndp.get_fnames()): msg = "Some of the functions are not present." raise_desc(ValueError, msg, fnames=fnames, ndp=ndp) for fname in fnames: F = ndp.get_ftype(fname) nn = get_name_for_fun_node(fname) name2ndp[nn] = dpwrap(Identity(F), fname, fname) connections.append(Connection(nn, fname, ndp_name, fname))
def eval_statement_ResShortcut4(r, context): check_isinstance(r, CDP.ResShortcut4) # requires rname1, rname2 rnames = get_odd_ops(unwrap_list(r.rnames)) for _ in rnames: rname = _.value if rname in context.var2resource: A = context.var2resource[rname] elif rname in context.fnames: # it's a function A = context.make_resource(get_name_for_fun_node(rname), rname) elif rname in context.constants: c = context.constants[rname] A = get_valuewithunits_as_resource(c, context) else: msg = 'Could not find required resource expression %r.' % rname raise DPSemanticError(msg, where=_.where) R = context.get_rtype(A) B = add_resource(rname, R, context, r) add_constraint(context, resource=A, function=B) # B >= A
def check_consistent_data(names, fnames, rnames, connections): from mocdp.comp.context import get_name_for_res_node, get_name_for_fun_node from mocdp.comp.context import is_res_node_name from mcdp_posets.types_universe import get_types_universe tu = get_types_universe() for n in names: try: check_good_name(n) except ValueError as e: msg = 'This name is not good.' raise_wrapped(ValueError, e, msg, names=names) isit, x = is_fun_node_name(n) if isit and not x in fnames: msg = 'The name for the node seems to be the one for a function.' raise_desc(ValueError, msg, n=n, fnames=fnames) isit, x = is_res_node_name(n) if isit and not x in rnames: if not n in rnames: msg = 'The name for the node seems to be the one for a resource.' raise_desc(ValueError, msg, n=n, rnames=rnames) for f in fnames: fnode = get_name_for_fun_node(f) if not fnode in names: msg = 'Expecting to see a node with the name of the function.' raise_desc(ValueError, msg, f=f, names=list(names.keys())) fn = names[fnode] if not f in fn.get_fnames(): msg = ('Expecting to see the special function node have function ' 'with function name.') raise_desc(ValueError, msg, f=f, fnode=fnode, fn=fn, fn_fnames=fn.get_fnames()) for r in rnames: rnode = get_name_for_res_node(r) if not rnode in names: msg = 'Expecting to see a node with the name of the resource.' raise_desc(ValueError, msg, r=r, names=list(names.keys())) rn = names[rnode] if not r in rn.get_rnames(): msg = ('Expecting to see the special resource node have resource ' 'with resource name.') raise_desc(ValueError, msg, r=r, rnode=rnode, rn=rn, rn_rnames=rn.get_rnames()) for c in connections: try: if not c.dp1 in names: raise_desc(ValueError, 'First DP %r not found.' % c.dp1, name=c.dp1, available=list(names)) if not c.s1 in names[c.dp1].get_rnames(): raise_desc(ValueError, 'Resource %r of first DP %r not found' % (c.s1, c.dp1), rname=c.s1, available=names[c.dp1].get_rnames()) if not c.dp2 in names: raise_desc(ValueError, 'Second DP %r not found.' % c.dp2, name=c.dp2, available=list(names)) if not c.s2 in names[c.dp2].get_fnames(): raise_desc(ValueError, 'Function %r of second DP %r not found.' % (c.s2, c.dp2), s2=c.s2, available=names[c.dp2].get_fnames()) R = names[c.dp1].get_rtype(c.s1) F = names[c.dp2].get_ftype(c.s2) try: tu.check_equal(R, F) except NotEqual as e: msg = 'Invalid connection %s' % c.__repr__() raise_wrapped(ValueError, e, msg, R=R, F=F) except ValueError as e: msg = 'Invalid connection %s.' % (c.__repr__()) raise_wrapped(ValueError, e, msg, compact=True)
def check_consistent_data(names, fnames, rnames, connections): from mocdp.comp.context import get_name_for_res_node, get_name_for_fun_node from mocdp.comp.context import is_res_node_name from mcdp_posets.types_universe import get_types_universe tu = get_types_universe() for n in names: try: check_good_name(n) except ValueError as e: msg = 'This name is not good.' raise_wrapped(ValueError, e, msg, names=names) isit, x = is_fun_node_name(n) if isit and not x in fnames: msg = 'The name for the node seems to be the one for a function.' raise_desc(ValueError, msg, n=n, fnames=fnames) isit, x = is_res_node_name(n) if isit and not x in rnames: if not n in rnames: msg = 'The name for the node seems to be the one for a resource.' raise_desc(ValueError, msg, n=n, rnames=rnames) for f in fnames: fnode = get_name_for_fun_node(f) if not fnode in names: msg = 'Expecting to see a node with the name of the function.' raise_desc(ValueError, msg, f=f, names=list(names.keys())) fn = names[fnode] if not f in fn.get_fnames(): msg = ('Expecting to see the special function node have function ' 'with function name.') raise_desc(ValueError, msg, f=f, fnode=fnode, fn=fn, fn_fnames=fn.get_fnames()) for r in rnames: rnode = get_name_for_res_node(r) if not rnode in names: msg = 'Expecting to see a node with the name of the resource.' raise_desc(ValueError, msg, r=r, names=list(names.keys())) rn = names[rnode] if not r in rn.get_rnames(): msg = ('Expecting to see the special resource node have resource ' 'with resource name.') raise_desc(ValueError, msg, r=r, rnode=rnode, rn=rn, rn_rnames=rn.get_rnames()) for c in connections: try: if not c.dp1 in names: raise_desc(ValueError, 'First DP %r not found.' % c.dp1, name=c.dp1, available=list(names)) if not c.s1 in names[c.dp1].get_rnames(): raise_desc(ValueError, 'Resource %r of first DP %r not found' %( c.s1, c.dp1), rname=c.s1, available=names[c.dp1].get_rnames()) if not c.dp2 in names: raise_desc(ValueError, 'Second DP %r not found.' % c.dp2, name=c.dp2, available=list(names)) if not c.s2 in names[c.dp2].get_fnames(): raise_desc(ValueError, 'Function %r of second DP %r not found.' % (c.s2, c.dp2), s2=c.s2, available=names[c.dp2].get_fnames()) R = names[c.dp1].get_rtype(c.s1) F = names[c.dp2].get_ftype(c.s2) try: tu.check_equal(R, F) except NotEqual as e: msg = 'Invalid connection %s' % c.__repr__() raise_wrapped(ValueError, e, msg, R=R, F=F) except ValueError as e: msg = 'Invalid connection %s.' % (c.__repr__()) raise_wrapped(ValueError, e, msg, compact=True)
def create_composite_(gdc0, ndp, plotting_info, SKIP_INITIAL): try: assert isinstance(ndp, CompositeNamedDP) # names2functions[name][fn] = item # names2resources[name][rn] = item names2resources = defaultdict(lambda: {}) names2functions = defaultdict(lambda: {}) if gdc0.should_I_enclose(ndp): if gdc0.yourname is None: container_label = '' else: if gdc0.yourname and gdc0.yourname[0] == '_': container_label = '' else: container_label = gdc0.yourname c = gdc0.newItem(container_label) gdc0.styleApply('container', c) gdc = gdc0.child_context(parent=c, yourname=gdc0.yourname) else: gdc = gdc0 for name, value in ndp.context.names.items(): # do not create these edges if SKIP_INITIAL: if is_function_with_one_connection_that_is_not_a_res_one(ndp, name): # print('Skipping extra node for is_function_with_one_connection %r' % name) # warnings.warn('hack') continue if SKIP_INITIAL: if is_resource_with_one_connection_that_is_not_a_fun_one(ndp, name): # print('skipping extra node for %r' % name) # warnings.warn('hack') continue if False: # this makes the nodes appear as red dots if is_function_with_no_connections(ndp, name): # only draw the balloon item = gdc.newItem("%s" % name) gdc.styleApply('unconnected', item) for fn in value.get_fnames(): names2functions[name][fn] = item for rn in value.get_rnames(): names2resources[name][rn] = item continue if is_resource_with_no_connections(ndp, name): # only draw the balloon instead of "Identity" node item = gdc.newItem("%s" % name) gdc.styleApply('unconnected', item) for fn in value.get_fnames(): names2functions[name][fn] = item for rn in value.get_rnames(): names2resources[name][rn] = item continue with gdc.child_context_yield(yourname=name, parent=gdc.parent) as child: plotting_info2 = RecursiveEdgeLabeling(plotting_info, name) f, r = create(child, value, plotting_info=plotting_info2) # print('name %s -> functions %s , resources = %s' % (name, list(f), list(r))) names2resources[name] = r names2functions[name] = f for rn in names2resources[name]: if resource_has_more_than_one_connected(ndp, name, rn): # create new splitter orig = names2resources[name][rn] split = gdc.newItem('') gdc.styleApply('splitter', split) l = gdc.newLink(orig, split) gdc.gg.propertyAppend(l, "constraint", "false") gdc.gg.propertyAppend(l, "weight", "0") gdc.styleApply('splitter_link', l) gdc.decorate_arrow_resource(l) names2resources[name][rn] = split ignore_connections = set() if SKIP_INITIAL: for name, value in ndp.context.names.items(): if is_function_with_one_connection_that_is_not_a_res_one(ndp, name): only_one = get_connections_to_function(ndp, name)[0] ignore_connections.add(only_one) if not only_one.dp2 in names2functions: msg = ('Cannot find function node ref for %r' % only_one.dp2 + ' while drawing one connection %s' % str(only_one)) # warnings.warn('giving up') # continue raise_desc(ValueError, msg, names=list(ndp.context.names), names2functions=list(names2functions)) node = names2functions[only_one.dp2][only_one.s2] names2functions[name][only_one.s1] = node # XXX: not really sure names2resources[name][only_one.s1] = node for name, value in ndp.context.names.items(): if is_resource_with_one_connection_that_is_not_a_fun_one(ndp, name): only_one = get_connections_to_resource(ndp, name)[0] ignore_connections.add(only_one) if not only_one.dp1 in names2resources: # warnings.warn('giving up') # continue raise ValueError('Cannot find function node ref for %r' % only_one.dp1 + ' while drawing one connection %s' % str(only_one)) node = names2resources[only_one.dp1][only_one.s1] names2resources[name][only_one.s2] = node # XXX: not really sure names2functions[name][only_one.s2] = node for c in ndp.context.connections: if c in ignore_connections: # print('ignoring connection %s' % str(c)) continue dpa = names2functions[c.dp2] n_a = dpa[c.s2] dpb = names2resources[c.dp1] n_b = dpb[c.s1] skip = gdc.should_I_skip_leq(ndp.context, c) ndp_first = ndp.context.names[c.dp1] ndp_second = ndp.context.names[c.dp2] second_simple = is_simple(ndp_second) first_simple = is_simple(ndp_first) any_simple = second_simple or first_simple both_simple = second_simple and first_simple ua = ndp.context.names[c.dp2].get_ftype(c.s2) ub = ndp.context.names[c.dp1].get_rtype(c.s1) if skip: l1 = gdc.newLink(n_b, n_a , label=get_signal_label(c.s1, ub)) else: box = gdc.newItem('') # '≼') gdc.styleApply("leq", box) l1_label = get_signal_label(c.s2, ua) dec = plotting_info.get_fname_label(ndp_name=(c.dp2,), fname=c.s2) if dec is not None: l1_label = get_signal_label_namepart(c.s2) + '\n' + dec if isinstance(ndp_second, SimpleWrap) and isinstance(ndp_second.dp, ResourceNode): l1_label = 'required ' + l1_label # print('Creating label with %r %s' % l1_label) l1 = gdc.newLink(box, n_a , label=l1_label) # if False: # gdc.gg.propertyAppend(l1, "headport", "w") l2_label = get_signal_label(c.s1, ub) if isinstance(ndp_first, SimpleWrap) and isinstance(ndp_first.dp, FunctionNode): l2_label = 'provided ' + l2_label dec = plotting_info.get_rname_label(ndp_name=(c.dp1,), rname=c.s1) if dec is not None: l2_label = get_signal_label_namepart(c.s1) + '\n' + dec l2 = gdc.newLink(n_b, box, label=l2_label) # if False: # gdc.gg.propertyAppend(l2, "tailport", "e") # # if False: # gdc.gg.propertyAppend(l1, 'constraint', 'false') # gdc.gg.propertyAppend(l2, 'constraint', 'false') if both_simple: weight = 0 elif any_simple: weight = 0.5 else: weight = 1 if any_simple: gdc.gg.propertyAppend(l2, 'weight', '%s' % weight) gdc.gg.propertyAppend(l1, 'weight', '%s' % weight) # gdc.gg.propertyAppend(l2, 'color', 'blue') # gdc.gg.propertyAppend(l1, 'color', 'blue') gdc.decorate_arrow_function(l1) gdc.decorate_arrow_resource(l2) unconnected_fun, unconnected_res = get_missing_connections(ndp.context) for (dp, fn) in unconnected_fun: x = gdc.newItem('') gdc.styleApply("unconnected_node", x) n = names2functions[dp][fn] F = ndp.context.names[dp].get_ftype(fn) label = get_signal_label(fn, F) it_is, _ = is_res_node_name(dp) if it_is: label = 'required ' + label l = gdc.newLink(x, n, label=label) gdc.decorate_arrow_function(l) # XXX? gdc.styleApply('unconnected_link', l) for (dp, rn) in unconnected_res: x = gdc.newItem('') gdc.styleApply("unconnected_node", x) n = names2resources[dp][rn] R = ndp.context.names[dp].get_rtype(rn) label = get_signal_label(rn, R) it_is, _ = is_fun_node_name(dp) if it_is: label = 'provided ' + label l = gdc.newLink(n, x, label=label) gdc.decorate_arrow_resource(l) # XXX? gdc.styleApply('unconnected_link', l) functions = {} resources = {} for rname in ndp.get_rnames(): name = get_name_for_res_node(rname) resources[rname] = list(names2resources[name].values())[0] for fname in ndp.get_fnames(): name = get_name_for_fun_node(fname) functions[fname] = list(names2functions[name].values())[0] if not (gdc is gdc0): gdc0.all_nodes.extend(gdc.all_nodes) return functions, resources except BaseException as e: raise msg = 'Could not draw diagram.' raise_wrapped(Exception, e, msg, names2functions=names2functions, names2resources=names2resources, ndp=ndp)
def __init__(self, library, options, flabels, F0s, f0s, rlabels, R0s, r0s, initial): f0s = list(f0s) F0s = list(F0s) r0s = list(r0s) R0s = list(R0s) for i, (fname, F0, f0) in enumerate(zip(flabels, F0s, f0s)): F0.belongs(f0) F = initial.get_ftype(fname) f0s[i] = express_value_in_isomorphic_space(F0, f0, F) F0s[i] = F for i, (rname, R0, r0) in enumerate(zip(rlabels, R0s, r0s)): R0.belongs(r0) R = initial.get_rtype(rname) r0s[i] = express_value_in_isomorphic_space(R0, r0, R) R0s[i] = R self.library = library self.options = options self.flabels = flabels self.rlabels = rlabels self.F0s = F0s self.R0s = R0s self.r0s = r0s self.f0s = f0s context = create_context0(flabels, F0s, f0s, rlabels, R0s, r0s, initial=initial) from mcdp_opt.optimization_state import OptimizationState unconnected = [] for o in options: ndp = library.load_ndp(o) try: ndp.check_fully_connected() except NotConnected as e: if o.lower() == "raspberrypi2": # pass unconnected.append(o) for u in unconnected: options.remove(u) print('Removing the unusable options %s' % sorted(unconnected)) print('Remaining with %s' % sorted(options)) lower_bounds = {} for fname, F0, f0 in zip(flabels, F0s, f0s): r = CResource(get_name_for_fun_node(fname), fname) lower_bounds[r] = F0.U(f0) from mcdp_opt.partial_result import get_lower_bound_ndp ndp, table = get_lower_bound_ndp(context) (_R, ur), _tableres = self.get_lower_bounds(ndp, table) self.num_created = 0 s0 = OptimizationState(self, options, context, executed=[], forbidden=set(), lower_bounds=lower_bounds, ur=ur, creation_order=self.get_next_creation()) self.root = s0 # open nodes self.states = [s0] self.actions = [(s0, ActionExpand())] # tuples of state, action # connected self.done = [] # impossible self.abandoned = [] # expanded self.expanded = [] # extra ndps not present in library self.additional = {} # str -> NamedDP self.iteration = 0 # for visualization self.G = nx.DiGraph() self.G_dom = nx.DiGraph() # domination graph
def create_composite_(gdc0, ndp, plotting_info, SKIP_INITIAL): try: assert isinstance(ndp, CompositeNamedDP) # names2functions[name][fn] = item # names2resources[name][rn] = item names2resources = defaultdict(lambda: {}) names2functions = defaultdict(lambda: {}) if gdc0.should_I_enclose(ndp): if gdc0.yourname is None: container_label = '' else: if gdc0.yourname and gdc0.yourname[0] == '_': container_label = '' else: container_label = gdc0.yourname c = gdc0.newItem(container_label) gdc0.styleApply('container', c) gdc = gdc0.child_context(parent=c, yourname=gdc0.yourname) else: gdc = gdc0 for name, value in ndp.context.names.items(): # do not create these edges if SKIP_INITIAL: if is_function_with_one_connection_that_is_not_a_res_one( ndp, name): # print('Skipping extra node for is_function_with_one_connection %r' % name) # warnings.warn('hack') continue if SKIP_INITIAL: if is_resource_with_one_connection_that_is_not_a_fun_one( ndp, name): # print('skipping extra node for %r' % name) # warnings.warn('hack') continue if False: # this makes the nodes appear as red dots if is_function_with_no_connections(ndp, name): # only draw the balloon item = gdc.newItem("%s" % name) gdc.styleApply('unconnected', item) for fn in value.get_fnames(): names2functions[name][fn] = item for rn in value.get_rnames(): names2resources[name][rn] = item continue if is_resource_with_no_connections(ndp, name): # only draw the balloon instead of "Identity" node item = gdc.newItem("%s" % name) gdc.styleApply('unconnected', item) for fn in value.get_fnames(): names2functions[name][fn] = item for rn in value.get_rnames(): names2resources[name][rn] = item continue with gdc.child_context_yield(yourname=name, parent=gdc.parent) as child: plotting_info2 = RecursiveEdgeLabeling(plotting_info, name) f, r = create(child, value, plotting_info=plotting_info2) # print('name %s -> functions %s , resources = %s' % (name, list(f), list(r))) names2resources[name] = r names2functions[name] = f for rn in names2resources[name]: if resource_has_more_than_one_connected(ndp, name, rn): # create new splitter orig = names2resources[name][rn] split = gdc.newItem('') gdc.styleApply('splitter', split) l = gdc.newLink(orig, split) gdc.gg.propertyAppend(l, "constraint", "false") gdc.gg.propertyAppend(l, "weight", "0") gdc.styleApply('splitter_link', l) gdc.decorate_arrow_resource(l) names2resources[name][rn] = split ignore_connections = set() if SKIP_INITIAL: for name, value in ndp.context.names.items(): if is_function_with_one_connection_that_is_not_a_res_one( ndp, name): only_one = get_connections_to_function(ndp, name)[0] ignore_connections.add(only_one) if not only_one.dp2 in names2functions: msg = ( 'Cannot find function node ref for %r' % only_one.dp2 + ' while drawing one connection %s' % str(only_one)) # warnings.warn('giving up') # continue raise_desc(ValueError, msg, names=list(ndp.context.names), names2functions=list(names2functions)) node = names2functions[only_one.dp2][only_one.s2] names2functions[name][only_one.s1] = node # XXX: not really sure names2resources[name][only_one.s1] = node for name, value in ndp.context.names.items(): if is_resource_with_one_connection_that_is_not_a_fun_one( ndp, name): only_one = get_connections_to_resource(ndp, name)[0] ignore_connections.add(only_one) if not only_one.dp1 in names2resources: # warnings.warn('giving up') # continue raise ValueError( 'Cannot find function node ref for %r' % only_one.dp1 + ' while drawing one connection %s' % str(only_one)) node = names2resources[only_one.dp1][only_one.s1] names2resources[name][only_one.s2] = node # XXX: not really sure names2functions[name][only_one.s2] = node for c in ndp.context.connections: if c in ignore_connections: # print('ignoring connection %s' % str(c)) continue dpa = names2functions[c.dp2] n_a = dpa[c.s2] dpb = names2resources[c.dp1] n_b = dpb[c.s1] skip = gdc.should_I_skip_leq(ndp.context, c) ndp_first = ndp.context.names[c.dp1] ndp_second = ndp.context.names[c.dp2] second_simple = is_simple(ndp_second) first_simple = is_simple(ndp_first) any_simple = second_simple or first_simple both_simple = second_simple and first_simple ua = ndp.context.names[c.dp2].get_ftype(c.s2) ub = ndp.context.names[c.dp1].get_rtype(c.s1) if skip: label = get_signal_label(c.s1, ub) l1 = gdc.newLink(n_b, n_a, label=label) else: box = gdc.newItem('') # '≼') # LEQ rel_to_8 = MCDPConstants.diagrams_fontsize / 8 diagrams_leqimagesize = MCDPConstants.diagrams_leqimagesize_rel * \ rel_to_8 gdc.gg.propertyAppend(box, 'height', diagrams_leqimagesize) gdc.styleApply("leq", box) l1_label = get_signal_label(c.s2, ua) dec = plotting_info.get_fname_label(ndp_name=(c.dp2, ), fname=c.s2) if dec is not None: l1_label = get_signal_label_namepart(c.s2) + '\n' + dec if isinstance(ndp_second, SimpleWrap) and isinstance( ndp_second.dp, ResourceNode): l1_label = 'required ' + l1_label # print('Creating label with %r %s' % l1_label) l1 = gdc.newLink(box, n_a, label=l1_label) # if False: # gdc.gg.propertyAppend(l1, "headport", "w") l2_label = get_signal_label(c.s1, ub) if isinstance(ndp_first, SimpleWrap) and isinstance( ndp_first.dp, FunctionNode): l2_label = 'provided ' + l2_label dec = plotting_info.get_rname_label(ndp_name=(c.dp1, ), rname=c.s1) if dec is not None: l2_label = get_signal_label_namepart(c.s1) + '\n' + dec l2 = gdc.newLink(n_b, box, label=l2_label) # if False: # gdc.gg.propertyAppend(l2, "tailport", "e") # # if False: # gdc.gg.propertyAppend(l1, 'constraint', 'false') # gdc.gg.propertyAppend(l2, 'constraint', 'false') if both_simple: weight = 0 elif any_simple: weight = 0.5 else: weight = 1 if any_simple: gdc.gg.propertyAppend(l2, 'weight', '%s' % weight) gdc.gg.propertyAppend(l1, 'weight', '%s' % weight) # gdc.gg.propertyAppend(l2, 'color', 'blue') # gdc.gg.propertyAppend(l1, 'color', 'blue') gdc.decorate_arrow_function(l1) gdc.decorate_arrow_resource(l2) unconnected_fun, unconnected_res = get_missing_connections(ndp.context) for (dp, fn) in unconnected_fun: x = gdc.newItem('') gdc.styleApply("unconnected_node", x) n = names2functions[dp][fn] F = ndp.context.names[dp].get_ftype(fn) label = get_signal_label(fn, F) it_is, _ = is_res_node_name(dp) if it_is: label = 'required ' + label l = gdc.newLink(x, n, label=label) gdc.decorate_arrow_function(l) # XXX? gdc.styleApply('unconnected_link', l) for (dp, rn) in unconnected_res: x = gdc.newItem('') gdc.styleApply("unconnected_node", x) n = names2resources[dp][rn] R = ndp.context.names[dp].get_rtype(rn) label = get_signal_label(rn, R) it_is, _ = is_fun_node_name(dp) if it_is: label = 'provided ' + label l = gdc.newLink(n, x, label=label) gdc.decorate_arrow_resource(l) # XXX? gdc.styleApply('unconnected_link', l) functions = {} resources = {} for rname in ndp.get_rnames(): name = get_name_for_res_node(rname) resources[rname] = list(names2resources[name].values())[0] for fname in ndp.get_fnames(): name = get_name_for_fun_node(fname) functions[fname] = list(names2functions[name].values())[0] if not (gdc is gdc0): gdc0.all_nodes.extend(gdc.all_nodes) return functions, resources except BaseException as e: raise msg = 'Could not draw diagram.' raise_wrapped(Exception, e, msg, names2functions=names2functions, names2resources=names2resources, ndp=ndp)