Exemple #1
0
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)
Exemple #2
0
def wrap_change_name_resource(ndp, rn, rn2):
    from mocdp.comp.wrap import dpwrap

    R = ndp.get_rtype(rn)
    tmpname = '__tmp_%s' % rn
    second = dpwrap(Identity(R), tmpname, rn2)
    from mocdp.comp.connection import connect2
    connections = set([Connection('-', rn, '-', tmpname)])
    return connect2(ndp, second, connections, split=[])
Exemple #3
0
def wrap_change_name_function(ndp, fn, fn2):
    from mocdp.comp.wrap import dpwrap

    F = ndp.get_ftype(fn)
    tmpname = '__tmp_%s' % fn
    first = dpwrap(Identity(F), fn2, tmpname)
    from mocdp.comp.connection import connect2
    connections = set([Connection('-', tmpname, '-', fn)])
    return connect2(first, ndp, connections, split=[])
Exemple #4
0
 def reorder_functions(ndp, rnames):
     F = ndp.get_ftypes(rnames)
     ndp0 = dpwrap(Identity(F), rnames, rnames)
     connections = [Connection('*', fn, '*', fn) for fn in rnames]
     return connect2(ndp0,
                     res,
                     set(connections),
                     split=[],
                     repeated_ok=True)
Exemple #5
0
 def reorder_resources(ndp, rnames):
     R = ndp.get_rtypes(rnames)
     ndp2 = dpwrap(Identity(R), rnames, rnames)
     connections = [Connection('*', rn, '*', rn) for rn in rnames]
     return connect2(res,
                     ndp2,
                     set(connections),
                     split=[],
                     repeated_ok=True)
Exemple #6
0
def connect_resources_to_outside(name2ndp, connections, ndp_name, rnames):
    """ 
        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(rnames).issubset(ndp.get_rnames()):
        msg = 'Some of the resources are not present.'
        raise_desc(ValueError, msg, rnames=rnames, ndp=ndp)

    for rn in rnames:
        nn = get_name_for_res_node(rn)
        R = ndp.get_rtype(rn)
        name2ndp[nn] = dpwrap(Identity(R), rn, rn)
        connections.append(Connection(ndp_name, rn, nn, rn))
Exemple #7
0
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))
Exemple #8
0
def add_muxes(inner,
              cs,
              s_muxed,
              inner_name='_inner0',
              mux1_name='_mux1',
              mux2_name='_mux2'):
    """
        Add muxes before and after inner 
        
       
                  ---(extraf)--|       |---(extrar)--
                     |--c1-----| inner |--c1--|
             s_muxed-|--c2-----|       |--c2--|--s_muxed
           
    """

    extraf = [f for f in inner.get_fnames() if not f in cs]
    extrar = [r for r in inner.get_rnames() if not r in cs]

    fnames = extraf + [s_muxed]
    rnames = extrar + [s_muxed]

    name2ndp = {}
    connections = []
    name2ndp[inner_name] = inner

    # Second mux
    if len(cs) == 1:
        F = inner.get_ftype(cs[0])
        nto1 = SimpleWrap(Identity(F), fnames=cs[0], rnames=s_muxed)
    else:
        types = inner.get_ftypes(cs)
        F = PosetProduct(types.subs)
        # [0, 1, 2]
        coords = list(range(len(cs)))
        mux = Mux(F, coords)
        nto1 = SimpleWrap(mux, fnames=cs, rnames=s_muxed)

    if len(cs) == 1:
        R = inner.get_rtype(cs[0])
        _1ton = SimpleWrap(Identity(R), fnames=s_muxed, rnames=cs[0])
    else:

        # First mux
        coords = list(range(len(cs)))
        R = mux.get_res_space()
        mux2 = Mux(R, coords)
        _1ton = SimpleWrap(mux2, fnames=s_muxed, rnames=cs)
        F2 = mux2.get_res_space()
        tu = get_types_universe()
        tu.check_equal(F, F2)

    name2ndp[mux1_name] = nto1
    name2ndp[mux2_name] = _1ton

    for n in cs:
        connections.append(Connection(inner_name, n, mux1_name, n))
    for n in cs:
        connections.append(Connection(mux2_name, n, inner_name, n))

    # Now add the remaining names
    connect_functions_to_outside(name2ndp,
                                 connections,
                                 ndp_name=inner_name,
                                 fnames=extraf)
    connect_resources_to_outside(name2ndp,
                                 connections,
                                 ndp_name=inner_name,
                                 rnames=extrar)

    connect_resources_to_outside(name2ndp,
                                 connections,
                                 ndp_name=mux1_name,
                                 rnames=[s_muxed])
    connect_functions_to_outside(name2ndp,
                                 connections,
                                 ndp_name=mux2_name,
                                 fnames=[s_muxed])

    outer = CompositeNamedDP.from_parts(name2ndp=name2ndp,
                                        connections=connections,
                                        fnames=fnames,
                                        rnames=rnames)
    return outer
Exemple #9
0
def connect2(ndp1, ndp2, connections, split, repeated_ok=False):
    """ 
        Note the argument split must be a list of strings so 
        that orders are preserved and deterministic. 
    """

    if ndp1 is ndp2:
        raise ValueError('Equal')

    def common(x, y):
        return len(set(x + y)) != len(set(x)) + len(set(y))

    if not repeated_ok:
        if (common(ndp1.get_fnames(), ndp2.get_fnames())
                or common(ndp1.get_rnames(), ndp2.get_rnames())):
            raise_desc(DPInternalError,
                       'repeated names',
                       ndp1=ndp1,
                       ndp2=ndp2,
                       connections=connections,
                       split=split)

    if len(set(split)) != len(split):
        msg = 'Repeated signals in split: %s' % str(split)
        raise ValueError(msg)
    try:
        if not connections:
            raise ValueError('Empty connections')

        #     |   |------------------------->A
        #     |   |          |-B1(split)----->
        # f1->|   |--B1----->|         ___
        #     | 1 |          |----B2->|   |   all_s2 = B2 + C2  all_s1 = B1 + C1
        #     |___| -C1--C2---------->| 2 |->r2
        # ---------D----------------->|___|
        #
        # ftot = f1 + D
        # rtot = A + b1 + r2
        # A + B + C = r1
        # B + C + D = f2
        # split = A + B

        # split = B1 is given
        # find B2 from B1
        def s2_from_s1(s1):
            for c in connections:
                if c.s1 == s1: return c.s2
            assert False, 'Cannot find connection with s1 = %s' % s1

        def s1_from_s2(s2):
            for c in connections:
                if c.s2 == s2: return c.s1
            assert False, 'Cannot find connection with s2 = %s' % s2

        f1 = ndp1.get_fnames()
        r1 = ndp1.get_rnames()
        f2 = ndp2.get_fnames()
        r2 = ndp2.get_rnames()

        all_s2 = set([c.s2 for c in connections])
        all_s1 = set([c.s1 for c in connections])

        # assert that all split are in s1
        for x in split:
            assert x in all_s1

        B1 = list(split)
        B2 = map(s2_from_s1, B1)
        C2 = list_diff(all_s2, B2)
        C1 = map(s1_from_s2, C2)
        A = list_diff(r1, B1 + C1)
        D = list_diff(f2, B2 + C2)

        # print('B1: %s' % B1)
        # print('B2: %s' % B2)
        # print('C2: %s' % C1)
        # print('C1: %s' % C1)
        # print(' A: %s' % A)
        # print(' D: %s' % D)
        fntot = f1 + D
        rntot = A + B1 + r2

        if there_are_repetitions(fntot) or there_are_repetitions(rntot):
            raise_desc(NotImplementedError,
                       'Repeated names',
                       fnames=fntot,
                       rnames=fntot)

        # now I can create Ftot and Rtot
        f1_types = ndp1.get_ftypes(f1)

        D_types = ndp2.get_ftypes(D)
        #         print('f1: %s' % f1)
        #         print('f1 types: %s' % f1_types)
        #         print('D: %s' % D)
        #         print('D types: %s' % D_types)

        Ftot = PosetProduct(tuple(list(f1_types) + list(D_types)))
        Rtot = PosetProduct(
            tuple(
                list(ndp1.get_rtypes(A)) + list(ndp1.get_rtypes(B1)) +
                list(ndp2.get_rtypes(r2))))

        # print('Ftot: %s' % str(Ftot))
        # print('      %s' % str(fntot))
        # print('Rtot: %s' % str(Rtot))
        # print('      %s' % str(rntot))
        assert len(fntot) == len(Ftot), (fntot, Ftot)
        assert len(rntot) == len(Rtot), (rntot, Rtot)

        # I can create the first muxer m1
        # from ftot to Product(f1, D)

        m1_for_f1 = [fntot.index(s) for s in f1]
        m1_for_D = [fntot.index(s) for s in D]

        m1coords = [m1_for_f1, m1_for_D]
        m1 = Mux(Ftot, m1coords)

        # print('m1: %s' % m1)
        # print('m1.R: %s' % m1.get_res_space())

        # Get Identity on D
        D_types = ndp2.get_ftypes(D)
        Id_D = Identity(D_types)

        ndp1_p = its_dp_as_product(ndp1)
        X = make_parallel(ndp1_p, Id_D)

        # make sure we can connect
        m1_X = make_series(m1, X)

        # print('m1_X = %s' % m1_X)
        # print('m1_X.R = %s' % m1_X.get_res_space()  )

        def coords_cat(c1, m):
            if m != ():
                return c1 + (m, )
            else:
                return c1

        A_B1_types = PosetProduct(
            tuple(ndp1.get_rtypes(A)) + tuple(ndp1.get_rtypes(B1)))
        Id_A_B1 = Identity(A_B1_types)
        ndp2_p = its_dp_as_product(ndp2)
        Z = make_parallel(Id_A_B1, ndp2_p)
        # print('Z.R = %s' % Z.get_res_space())
        # print('B1: %s' % B1)
        # print('R2: %s' % r2)
        m2coords_A = [(0, (A + B1).index(x)) for x in A]
        m2coords_B1 = [(0, (A + B1).index(x)) for x in B1]
        m2coords_r2 = [(1, r2.index(x)) for x in r2]
        m2coords = m2coords_A + m2coords_B1 + m2coords_r2
        # print('m2coords_A: %r' % m2coords_A)
        # print('m2coords_B1: %r' % m2coords_B1)
        # print('m2coords_r2: %r' % m2coords_r2)
        # print('m2coords: %r' % m2coords)

        # print('Z.R: %s' % Z.get_res_space())
        m2 = Mux(Z.get_res_space(), m2coords)

        assert len(m2.get_res_space()) == len(rntot), ((m2.get_res_space(),
                                                        rntot))
        # make sure we can connect
        make_series(Z, m2)

        #
        #  f0 -> |m1| -> | X | -> |Y |-> |Z| -> |m2| -> r0
        #
        # X = dp1 | Id_D
        # Z = Id_B1 | dp2

        #      ___
        #     |   |------------------------->A
        #     |   |          |-B1----------->
        # f1->|   |--B1----->|         ___
        #     | 1 |          |----B2->|   |
        #     |___| -C1-----------C2->| 2 |->r2
        # ---------D----------------->|___|

        #      ___
        #     |   |-------------------------------->A
        #     |   |  .            *-B1-------.----->
        # f1->|   |  . |--B1----->*          .   ___
        #     | 1 |--.-|          *----B2->| .  |   |
        #     |___|  . |-C1------------C2->|-.->| 2 |->r2
        # ---------D-.-------------------->| .  |___|
        # m1  | X | Y                        |  Z    | m2

        # I need to write the muxer
        # look at the end
        # iterate 2's functions

        Y_coords_A_B1 = []
        for x in A:
            Y_coords_A_B1.append((0, r1.index(x)))
        for x in B1:
            Y_coords_A_B1.append((0, r1.index(x)))

        Y_coords_B2_C2_D = []
        for x in f2:
            if (x in B2) or (x in C2):
                Y_coords_B2_C2_D.append((0, r1.index(s1_from_s2(x))))
                assert x not in D
            elif x in D:
                Y_coords_B2_C2_D.append((1, D.index(x)))
            else:
                assert False

        # print ('Y_coords_A_B1: %s' % Y_coords_A_B1)
        # print ('Y_coords_B2_C2_D: %s' % Y_coords_B2_C2_D)
        Y_coords = [Y_coords_A_B1, Y_coords_B2_C2_D]
        Y = Mux(m1_X.get_res_space(), Y_coords)

        # m1* Xp Y* Zp m2*
        # Let's make series
        # m1_X is simplifed
        Y_Z = make_series(Y, Z)
        Y_Z_m2 = make_series(Y_Z, m2)

        res_dp = make_series(m1_X, Y_Z_m2)

        fnames = fntot
        rnames = rntot

        res_dp, fnames, rnames = simplify_if_only_one_name(
            res_dp, fnames, rnames)

        # print('res_dp: %s' % res_dp)
        res = dpwrap(res_dp, fnames, rnames)

        return res

    except Exception as e:
        msg = 'connect2() failed'
        raise_wrapped(DPInternalError,
                      e,
                      msg,
                      ndp1=ndp1,
                      ndp2=ndp2,
                      connections=connections,
                      split=split)
Exemple #10
0
def cndp_flatten(ndp):
    check_isinstance(ndp, CompositeNamedDP)

    name2ndp = ndp.get_name2ndp()
    connections = ndp.get_connections()
    fnames = ndp.get_fnames()
    rnames = ndp.get_rnames()

    names2 = {}
    connections2 = []

    proxy_functions = defaultdict(lambda: dict())  # proxy[name][fname]
    proxy_resources = defaultdict(lambda: dict())

    for name, n0 in name2ndp.items():
        # add empty (in case they have no functions/resources)
        proxy_functions[name] = {}
        proxy_resources[name] = {}

        n1 = n0.flatten()

        if isinstance(n1, CompositeNamedDP):
            nn = flatten_add_prefix(n1, prefix=name)
        else:
            nn = n1

        if isinstance(nn, CompositeNamedDP):
            #             nn_connections = nn.get_connections()
            for name2, ndp2 in nn.get_name2ndp().items():
                assert not name2 in names2
                isitf, is_fname = is_fun_node_name(name2)
                isitr, is_rname = is_res_node_name(name2)

                if (isitf or isitr):
                    # connected_to_something = is_dp_connected(name2, nn_connections)
                    # do not add the identity nodes
                    # that represent functions or resources
                    # except if they are unconnected

                    # add_identities = not connected_to_something
                    add_identities = True

                    if not add_identities:  # pragma: no cover
                        continue
                    else:
                        # think of the case where there are a f and r with
                        # same name
                        if isitf:
                            use_name = is_fname + '_f'
                        if isitr:
                            use_name = is_rname + '_r'

                        assert not use_name in names2, use_name
                        names2[use_name] = ndp2

                        if isitf:
                            proxy_functions[name][is_fname] = (
                                use_name, ndp2.get_fnames()[0])

                        if isitr:
                            proxy_resources[name][is_rname] = (
                                use_name, ndp2.get_rnames()[0])

                else:
                    assert not name2 in names2
                    names2[name2] = ndp2

            for c in nn.get_connections():
                # is it a connection to a function

                if False:
                    isitf, fn = is_fun_node_name(c.dp1)
                    isitr, rn = is_res_node_name(c.dp2)

                    if isitf and isitr:
                        # This is the case where there is a straight connection
                        # from function to resource:
                        #
                        # f = instance mcdp {
                        #     provides a [dimensionless]
                        #     requires c [dimensionless]
                        #
                        #     c >= a
                        # }
                        # In this case, we need to add an identity
                        new_name = '_%s_pass_through_%s' % (name, c.s2)
                        F = nn.get_name2ndp()[c.dp1].get_ftype(c.s1)
                        ndp_pass = SimpleWrap(Identity(F),
                                              fnames=fn,
                                              rnames=rn)
                        assert not new_name in names2
                        names2[new_name] = ndp_pass
                        proxy_functions[name][fn] = (new_name, fn)
                        proxy_resources[name][rn] = (new_name, rn)
                        continue

                    if isitf:
                        proxy_functions[name][fn] = (c.dp2, c.s2)
                        continue

                    if isitr:
                        proxy_resources[name][rn] = (c.dp1, c.s1)
                        continue

                isitf, fn = is_fun_node_name(c.dp1)
                if isitf:
                    dp1 = fn + '_f'
                    assert dp1 in names2
                else:
                    dp1 = c.dp1

                isitr, rn = is_res_node_name(c.dp2)
                if isitr:
                    dp2 = rn + '_r'
                    assert dp2 in names2
                else:
                    dp2 = c.dp2

                assert dp1 in names2
                assert dp2 in names2
                assert c.s1 in names2[dp1].get_rnames()
                assert c.s2 in names2[dp2].get_fnames()
                c2 = Connection(dp1=dp1, s1=c.s1, dp2=dp2, s2=c.s2)
                connections2.append(c2)
        else:
            for fn in nn.get_fnames():
                proxy_functions[name][fn] = (name, fn)

            for rn in nn.get_rnames():
                proxy_resources[name][rn] = (name, rn)

            assert not name in names2
            names2[name] = nn

    # check that these were correctly generated:
    #  proxy_functions
    #  proxy_resources
    def exploded(name):
        return isinstance(name2ndp[name], CompositeNamedDP)

    # print list(proxy_resources)
    errors = []
    for name, n0 in name2ndp.items():
        try:

            assert name in proxy_functions, name
            assert name in proxy_resources
            if exploded(name):
                for fname in n0.get_fnames():
                    newfname = "%s/%s" % (name, fname)
                    assert newfname in proxy_functions[name], (
                        newfname, proxy_functions[name])
                for rname in n0.get_rnames():
                    newrname = "%s/%s" % (name, rname)
                    assert newrname in proxy_resources[name], (
                        newrname, proxy_resources[name])
            else:
                for fname in n0.get_fnames():
                    assert fname in proxy_functions[name], (
                        fname, proxy_functions[name])
                for rname in n0.get_rnames():
                    assert rname in proxy_resources[name]
        except Exception as e:  # pragma: no cover
            s = '%s:\n %s %s \n\n%s' % (name, proxy_resources[name],
                                        proxy_functions[name], e)
            errors.append(s)
    if errors:  # pragma: no cover
        s = "\n\n".join(errors)
        s += '%s %s' % (proxy_resources, proxy_functions)
        raise Exception(s)

    for c in connections:
        dp2 = c.dp2
        s2 = c.s2
        dp1 = c.dp1
        s1 = c.s1

        dp2_was_exploded = isinstance(name2ndp[dp2], CompositeNamedDP)
        if dp2_was_exploded:
            if not dp2 in proxy_functions:  # pragma: no cover
                msg = 'Bug: cannot find dp2.'
                raise_desc(DPInternalError,
                           msg,
                           dp2=dp2,
                           keys=list(proxy_functions),
                           c=c)

            (dp2_, s2_) = proxy_functions[dp2]["%s/%s" % (dp2, s2)]

            if not dp2_ in names2:  # pragma: no cover
                raise_desc(DPInternalError,
                           "?",
                           dp2_=dp2_,
                           c=c,
                           names2=sorted(names2))
        else:
            dp2_ = dp2
            s2_ = s2

        dp1_was_exploded = isinstance(name2ndp[dp1], CompositeNamedDP)
        if dp1_was_exploded:
            (dp1_, s1_) = proxy_resources[dp1]["%s/%s" % (dp1, s1)]
        else:
            dp1_ = dp1
            s1_ = s1

        assert dp1_ in names2

        assert s1_ in names2[dp1_].get_rnames(), (s1_,
                                                  names2[dp1_].get_rnames())

        assert dp2_ in names2
        assert s2_ in names2[dp2_].get_fnames(), (s2_,
                                                  names2[dp2_].get_fnames())

        c2 = Connection(dp1=dp1_, s1=s1_, dp2=dp2_, s2=s2_)
        connections2.append(c2)

    ndp_res = CompositeNamedDP.from_parts(names2, connections2, fnames, rnames)

    ndp_simplified = simplify_identities(ndp_res)
    return ndp_simplified
Exemple #11
0
def Identity1():
    F = parse_poset('V')
    return Identity(F)
Exemple #12
0
def get_primitivedp():
    from mcdp_dp import Identity
    from mcdp_posets import Nat
    return Identity(Nat())

    #mcdp_primitive