def simplify_if_only_one_name(res_dp, fnames, rnames): if len(fnames) == 1: fnames = fnames[0] funsp = res_dp.get_fun_space() res_dp = make_series(Mux(funsp[0], [()]), res_dp) if len(rnames) == 1: rnames = rnames[0] ressp = res_dp.get_res_space() res_dp = make_series(res_dp, Mux(ressp, 0)) return res_dp, fnames, rnames
def its_dp_as_product(ndp): """ If fnames == 1 """ dp = ndp.get_dp() if len(ndp.get_fnames()) == 1: F0 = dp.get_fun_space() F = PosetProduct((F0, )) down = Mux(F, 0) dp = make_series(down, dp) if len(ndp.get_rnames()) == 1: R0 = dp.get_res_space() lift = Mux(R0, [()]) dp = make_series(dp, lift) return dp
def its_dp_as_product(ndp): """ If fnames == 1 """ dp = ndp.get_dp() if len(ndp.get_fnames()) == 1: F0 = dp.get_fun_space() F = PosetProduct((F0,)) down = Mux(F, 0) dp = make_series(down, dp) if len(ndp.get_rnames()) == 1: R0 = dp.get_res_space() lift = Mux(R0, [()]) dp = make_series(dp, lift) return dp
def eval_ndp_dpwrap(r, context): tu = get_types_universe() statements = unwrap_list(r.statements) fun = [x for x in statements if isinstance(x, CDP.FunStatement)] res = [x for x in statements if isinstance(x, CDP.ResStatement)] assert len(fun) + len(res) == len(statements), statements impl = r.impl from .eval_primitivedp_imp import eval_primitivedp dp = eval_primitivedp(impl, context) fnames = [f.fname.value for f in fun] rnames = [r.rname.value for r in res] if len(fnames) == 1: use_fnames = fnames[0] else: use_fnames = fnames if len(rnames) == 1: use_rnames = rnames[0] else: use_rnames = rnames dp_F = dp.get_fun_space() dp_R = dp.get_res_space() # Check that the functions are the same want_Fs = tuple([eval_space(f.unit, context) for f in fun]) if len(want_Fs) == 1: want_F = want_Fs[0] else: want_F = PosetProduct(want_Fs) want_Rs = tuple([eval_space(r.unit, context) for r in res]) if len(want_Rs) == 1: want_R = want_Rs[0] else: want_R = PosetProduct(want_Rs) mcdp_dev_warning('Not sure about this') dp_prefix = get_conversion(want_F, dp_F) dp_postfix = get_conversion(dp_R, want_R) if dp_prefix is not None: dp = make_series(dp_prefix, dp) if dp_postfix is not None: dp = make_series(dp, dp_postfix) try: w = SimpleWrap(dp=dp, fnames=use_fnames, rnames=use_rnames) except ValueError as e: raise DPSemanticError(str(e), r.where) ftypes = w.get_ftypes(fnames) rtypes = w.get_rtypes(rnames) ftypes_expected = PosetProduct(tuple([eval_space(f.unit, context) for f in fun])) rtypes_expected = PosetProduct(tuple([eval_space(r.unit, context) for r in res])) try: tu.check_equal(ftypes, ftypes_expected) tu.check_equal(rtypes, rtypes_expected) except NotEqual as e: msg = 'The types in the description do not match.' raise_wrapped(DPSemanticError, e, msg, dp=dp, ftypes=ftypes, ftypes_expected=ftypes_expected, rtypes=rtypes, rtypes_expected=rtypes_expected, compact=True) return w
def eval_ndp_dpwrap(r, context): tu = get_types_universe() statements = unwrap_list(r.statements) fun = [x for x in statements if isinstance(x, CDP.FunStatement)] res = [x for x in statements if isinstance(x, CDP.ResStatement)] assert len(fun) + len(res) == len(statements), statements impl = r.impl from .eval_primitivedp_imp import eval_primitivedp dp = eval_primitivedp(impl, context) fnames = [f.fname.value for f in fun] rnames = [r.rname.value for r in res] if len(fnames) == 1: use_fnames = fnames[0] else: use_fnames = fnames if len(rnames) == 1: use_rnames = rnames[0] else: use_rnames = rnames dp_F = dp.get_fun_space() dp_R = dp.get_res_space() # Check that the functions are the same want_Fs = tuple([eval_space(f.unit, context) for f in fun]) if len(want_Fs) == 1: want_F = want_Fs[0] else: want_F = PosetProduct(want_Fs) want_Rs = tuple([eval_space(r.unit, context) for r in res]) if len(want_Rs) == 1: want_R = want_Rs[0] else: want_R = PosetProduct(want_Rs) mcdp_dev_warning('Not sure about this') dp_prefix = get_conversion(want_F, dp_F) dp_postfix = get_conversion(dp_R, want_R) if dp_prefix is not None: dp = make_series(dp_prefix, dp) if dp_postfix is not None: dp = make_series(dp, dp_postfix) try: w = SimpleWrap(dp=dp, fnames=use_fnames, rnames=use_rnames) except ValueError as e: raise DPSemanticError(str(e), r.where) ftypes = w.get_ftypes(fnames) rtypes = w.get_rtypes(rnames) ftypes_expected = PosetProduct( tuple([eval_space(f.unit, context) for f in fun])) rtypes_expected = PosetProduct( tuple([eval_space(r.unit, context) for r in res])) try: tu.check_equal(ftypes, ftypes_expected) tu.check_equal(rtypes, rtypes_expected) except NotEqual as e: msg = 'The types in the description do not match.' raise_wrapped(DPSemanticError, e, msg, dp=dp, ftypes=ftypes, ftypes_expected=ftypes_expected, rtypes=rtypes, rtypes_expected=rtypes_expected, compact=True) return w
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)
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)