Exemplo n.º 1
0
 def _create_evar(member, name, eblock, index_set):
     # Name is same, conflicts are prevented by a check in Port.add.
     # The new var will mirror the original var and have same index set.
     # We only need one evar per arc, so check if it already exists
     # before making a new one.
     evar = eblock.component(name)
     if evar is None:
         evar = replicate_var(member, name, eblock, index_set)
     return evar
Exemplo n.º 2
0
    def _validate_and_expand_port_set(self, ports):
        ref = {}
        # First, go through the ports and get the superset of all fields
        for p in ports:
            for k, v in iteritems(p.vars):
                if k in ref:
                    # We have already seen this var
                    continue
                if v is None:
                    # This is an implicit var
                    continue
                # OK: New var, so add it to the reference list
                _len = (-1 if not v.is_indexed() else len(v))
                ref[k] = (v, _len, p, p.rule_for(k))

        if not ref:
            logger.warning("Cannot identify a reference port: no ports "
                           "in the port set have assigned variables:\n\t(%s)" %
                           ', '.join(sorted(p.name
                                            for p in itervalues(ports))))
            return ref

        # Now make sure that ports match
        empty_or_partial = []
        for p in ports:
            p_is_partial = False
            if not p.vars:
                # This is an empty port and should be defined with
                # "auto" vars
                empty_or_partial.append(p)
                continue

            for k, v in iteritems(ref):
                if k not in p.vars:
                    raise ValueError(
                        "Port mismatch: Port '%s' missing variable "
                        "'%s' (appearing in reference port '%s')" %
                        (p.name, k, v[2].name))
                _v = p.vars[k]
                if _v is None:
                    if not p_is_partial:
                        empty_or_partial.append(p)
                        p_is_partial = True
                    continue
                _len = (-1 if not _v.is_indexed() else len(_v))
                if (_len >= 0) ^ (v[1] >= 0):
                    raise ValueError(
                        "Port mismatch: Port variable '%s' mixing "
                        "indexed and non-indexed targets on ports '%s' "
                        "and '%s'" % (k, v[2].name, p.name))
                if _len >= 0 and _len != v[1]:
                    raise ValueError(
                        "Port mismatch: Port variable '%s' index "
                        "mismatch (%s elements in reference port '%s', "
                        "but %s elements in port '%s')" %
                        (k, v[1], v[2].name, _len, p.name))
                if v[1] >= 0 and len(v[0].index_set() ^ _v.index_set()):
                    raise ValueError(
                        "Port mismatch: Port variable '%s' has "
                        "mismatched indices on ports '%s' and '%s'" %
                        (k, v[2].name, p.name))
                if p.rule_for(k) is not v[3]:
                    raise ValueError("Port mismatch: Port variable '%s' has "
                                     "different rules on ports '%s' and '%s'" %
                                     (k, v[2].name, p.name))

        # as we are adding things to the model, sort by key so that
        # the order things are added is deterministic
        sorted_refs = sorted(iteritems(ref))
        if len(empty_or_partial) > 1:
            # This is expensive (names aren't cheap), but does result in
            # a deterministic ordering
            empty_or_partial.sort(key=lambda x: x.getname(
                fully_qualified=True, name_buffer=self._name_buffer))

        # Fill in any empty ports
        for p in empty_or_partial:
            block = p.parent_block()
            for k, v in sorted_refs:
                if k in p.vars and p.vars[k] is not None:
                    continue

                vname = unique_component_name(
                    block, '%s_auto_%s' %
                    (p.getname(fully_qualified=True,
                               name_buffer=self._name_buffer), k))

                new_var = replicate_var(v[0], vname, block)

                # add this new variable to the port so that it has a rule
                p.add(new_var, k, rule=v[3])

        return ref
Exemplo n.º 3
0
    def _validate_and_expand_port_set(self, ports):
        ref = {}
        # First, go through the ports and get the superset of all fields
        for p in ports:
            for k, v in iteritems(p.vars):
                if k in ref:
                    # We have already seen this var
                    continue
                if v is None:
                    # This is an implicit var
                    continue
                # OK: New var, so add it to the reference list
                _len = (
                    -1 if not v.is_indexed()
                    else len(v))
                ref[k] = (v, _len, p, p.rule_for(k))

        if not ref:
            logger.warning(
                "Cannot identify a reference port: no ports "
                "in the port set have assigned variables:\n\t(%s)"
                % ', '.join(sorted(p.name for p in itervalues(ports))))
            return ref

        # Now make sure that ports match
        empty_or_partial = []
        for p in ports:
            p_is_partial = False
            if not p.vars:
                # This is an empty port and should be defined with
                # "auto" vars
                empty_or_partial.append(p)
                continue

            for k, v in iteritems(ref):
                if k not in p.vars:
                    raise ValueError(
                        "Port mismatch: Port '%s' missing variable "
                        "'%s' (appearing in reference port '%s')" %
                        (p.name, k, v[2].name))
                _v = p.vars[k]
                if _v is None:
                    if not p_is_partial:
                        empty_or_partial.append(p)
                        p_is_partial = True
                    continue
                _len = (
                    -1 if not _v.is_indexed()
                    else len(_v))
                if (_len >= 0) ^ (v[1] >= 0):
                    raise ValueError(
                        "Port mismatch: Port variable '%s' mixing "
                        "indexed and non-indexed targets on ports '%s' "
                        "and '%s'" %
                        (k, v[2].name, p.name))
                if _len >= 0 and _len != v[1]:
                    raise ValueError(
                        "Port mismatch: Port variable '%s' index "
                        "mismatch (%s elements in reference port '%s', "
                        "but %s elements in port '%s')" %
                        (k, v[1], v[2].name, _len, p.name))
                if v[1] >= 0 and len(v[0].index_set() ^ _v.index_set()):
                    raise ValueError(
                        "Port mismatch: Port variable '%s' has "
                        "mismatched indices on ports '%s' and '%s'" %
                        (k, v[2].name, p.name))
                if p.rule_for(k) is not v[3]:
                    raise ValueError(
                        "Port mismatch: Port variable '%s' has "
                        "different rules on ports '%s' and '%s'" %
                        (k, v[2].name, p.name))

        # as we are adding things to the model, sort by key so that
        # the order things are added is deterministic
        sorted_refs = sorted(iteritems(ref))
        if len(empty_or_partial) > 1:
            # This is expensive (names aren't cheap), but does result in
            # a deterministic ordering
            empty_or_partial.sort(key=lambda x: x.getname(
                fully_qualified=True, name_buffer=self._name_buffer))

        # Fill in any empty ports
        for p in empty_or_partial:
            block = p.parent_block()
            for k, v in sorted_refs:
                if k in p.vars and p.vars[k] is not None:
                    continue

                vname = unique_component_name(
                    block, '%s_auto_%s' % (p.getname(
                        fully_qualified=True, name_buffer=self._name_buffer),k))

                new_var = replicate_var(v[0], vname, block)

                # add this new variable to the port so that it has a rule
                p.add(new_var, k, rule=v[3])

        return ref