Exemplo n.º 1
0
def tile_expr( _expr ):
    tiles = []
    expr = copy.deepcopy( _expr )
    lhs, rhs = expr.get_children()
    if isinstance( rhs, Predicate ):
        tiles_per_arg = []
        for i, arg in enumerate( rhs.get_children() ):
            if not isOperand( arg ):
                tiles_per_arg.append( list(all_tilings( arg )) )
            else:
                tiles_per_arg.append( [[arg]] )
        cross = itertools.product( *tiles_per_arg )
        for comb in cross:
            new_pred = copy.deepcopy( rhs )
            new_ch = [ t[-1] for t in comb ]
            for i,ch in enumerate( new_ch ):
                new_pred.set_children( i, ch )
            updates = list(itertools.chain.from_iterable( [t[:-1] for t in comb] ))
            tiles.append( updates + [Equal([lhs, new_pred])] )
    else:
        if isOperand(rhs):
            tiles.append( [_expr] )
        else:
            for tiling in all_tilings( rhs ):
                last = tiling.pop() # This is just a (temporary) symbol (output of one-to-last)
                one_to_last = tiling.pop()
                lhs, rhs = expr.get_children()
                one_to_last.set_children( 0, lhs ) # assign one-to-last to actual lhs of eq
                tiling.append( one_to_last )
                tiles.append( tiling )
    return tiles
Exemplo n.º 2
0
def all_tilings( expr ):
    ongoing = [ [expr] ]
    while len( ongoing ) > 0:
        alg = ongoing.pop()
        to_tile = alg.pop()
        if isOperand( to_tile ):
            alg.append( to_tile )
            yield alg
            continue
        to_tile = replace_all( copy.deepcopy( to_tile), grouping_rules )
        for collection in reversed(instruction_set):
            matched_in_this_level = False ### These are just control vars
                                          ### to avoid redundancies
            for instr in collection:
                for node in to_tile.iterate_preorder():
                    # To avoid redundancies
                    matched_this_node = [] ###
                    if isinstance( instr, tuple ): # A way to deactivate some for quick development/debugging?
                        continue
                    for _m in instr.match( node ):
                        matched_in_this_level = True ###
                        #_T = TOS.new_temp()
                        new = copy.deepcopy( to_tile )
                        #tile, new = instr.tile( new, _m, _T )
                        tile, new = instr.tile( new, node, _m )
                        lhs, rhs = tile.get_children()
                        if rhs not in matched_this_node: ###
                            matched_this_node.append( rhs ) ###
                            ongoing.append( alg[:] + [tile, new] )
                            # Set size of new temporary
                            lhs.children[0].size = rhs.get_size()
                        else:
                            # Aestetic. Simply to avoid missing T? values.
                            TOS.push_back_temp( )
                            TOS._TOS.unset_operand( tile.children[0].children[0] )
            if matched_in_this_level: ###
                break
Exemplo n.º 3
0
    def generate_predicate_before(
            self, pme, trav, linv,
            linv_obj):  # [TODO] Cleanup, no need for linv AND linv_obj
        new = [copy.deepcopy(expr) for expr in itertools.chain(*linv)]
        # Repartition
        reparts = dict()
        repart_rules = []
        for op in linv_obj.linv_operands:
            part = linv_obj.linv_operands_basic_part[op.get_name()]
            # [CHECK] _shape or not? Regular one needed for inheritance
            repart = repartition(op, part.shape, trav[op.get_name()])
            #
            #repart_shape = {(1,1):(1,1), (1,2):(1,3), (2,1):(3,1), (2,2):(3,3)}[part.shape]
            #repart = repartition_shape( op, repart_shape )
            #repart = repart_group( repart, repart_shape, trav[op.get_name()] )
            #
            for part_op, repart_op in zip(itertools.chain(*part),
                                          itertools.chain(*repart)):
                repart_rules.append(
                    RewriteRule(part_op, Replacement(repart_op)))
            reparts[op.get_name()] = repart
        # Apply repartitionings
        new = [replace(expr, repart_rules) for expr in new]

        # Explicit functions to BlockedExpression
        #  First flatten args, then replace
        for expr in new:
            lhs, rhs = expr.get_children()
            if isinstance(rhs, Predicate):
                for i, arg in enumerate(rhs.get_children()):
                    #rhs.set_children( i, flatten_blocked_operation(arg) )
                    rhs.set_children(i, flatten_blocked_operation_click(arg))
        new = [replace(expr, known_pmes) for expr in new]

        # Operators applied to BlockedExpression, into BlockedExpressions
        for expr in new:
            if isinstance(expr, BlockedExpression):
                continue
            _, rhs = expr.get_children()
            #print( rhs ) # [TODO] Maybe "Sylv(...)"!!!
            #rhs = flatten_blocked_operation( rhs )
            rhs = flatten_blocked_operation_click(rhs)
            expr.set_children(1, rhs)

        # Flatten left-hand sides of the previous type of expressions
        for expr in new:
            if isinstance(expr, BlockedExpression):
                continue
            lhs, rhs = expr.get_children()
            new_lhs = []
            for out in lhs:
                if isinstance(out, Symbol):  # this is a temporary one
                    out.size = rhs.get_size()
                    #part = partition_shape( out, rhs.shape )
                    part = partition_shape(out, tuple(rhs.shape))
                    new_lhs.append(part)
                else:
                    new_lhs.append(out)
            lhs = BlockedExpression(map_thread(NList, new_lhs, 2), (0, 0),
                                    rhs.shape)
            expr.set_children(0, lhs)
        # Flatten the last type of expressions
        final = []
        for expr in new:
            if isinstance(expr, BlockedExpression):
                final.extend([
                    simplify(to_canonical(eq)) for eq in itertools.chain(*expr)
                ])
            else:
                lhs, rhs = expr.get_children()
                final.extend([
                    simplify(to_canonical(eq))
                    for eq in itertools.chain.from_iterable(
                        map_thread(Equal, [lhs, rhs], 2))
                ])
        final = filter_zero_zero(final)
        # remove expressions of the type " B_10^T = ..." (e.g., in symv)"
        _final = final
        final = []
        for expr in _final:
            lhs, rhs = expr.children
            lhs = lhs.children
            # [FIXME] == 1 only to make sure it does not affect other cases.
            # Just want to let them break and study them in the future
            if len(lhs) == 1 and (not isOperand(lhs[0]) or lhs[0].isZero()):
                continue
            final.append(expr)
        #
        # expand in terms of input parts
        #
        #expand_rules = list(itertools.chain(*self.expr_to_rule_lhs_rhs( final )))
        #for expr in final:
        #expr.children[1] = simplify(to_canonical(replace_all(copy.deepcopy(expr.children[1]), expand_rules)))
        #
        # Print and return
        #
        for expr in final:
            print("*   ", expr)

        return (reparts, final)
Exemplo n.º 4
0
 def expr_to_rule_rhs_lhs(self, predicates):
     rules = []
     t = PatternStar("t")
     l = PatternStar("l")
     ld = PatternDot("ld")
     r = PatternStar("r")
     for p in predicates:
         pr = []
         lhs, rhs = p.children
         if len(lhs.children) == 1:
             #lhs_sym = WrapOutBef( lhs.children[0] )
             lhs_sym = lhs.children[0]
             if isinstance(rhs, Plus):
                 # t___ + rhs -> t + lhs
                 repl_f = (lambda lhs: lambda d: Plus(d["t"].children +
                                                      [lhs]))(lhs_sym)
                 pr.append(
                     RewriteRule(Plus([t] + rhs.children),
                                 Replacement(repl_f)))
                 # t___ + l___ rhs_i r___ + ... -> t + l lhs r
                 repl_f = (lambda lhs: lambda d: Plus(d["t"].children + [
                     Times(d["l"].children + [lhs] + d["r"].children)
                 ]))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Plus([t] + [
                             Times([l] + [ch] + [r]) for ch in rhs.children
                         ]), Replacement(repl_f)))
                 repl_f = (lambda lhs: lambda d: Plus(d["t"].children + [
                     Times([simplify(to_canonical(Minus([lhs])))] + d["r"].
                           children)
                 ]))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Plus([t] + [
                             Times([simplify(to_canonical(Minus([ch])))] +
                                   [r]) for ch in rhs.children
                         ]), Replacement(repl_f)))
                 # A - B C in  L B C R + -L A R  (minus pushed all the way to the left, and whole thing negated)
                 repl_f = (lambda lhs: lambda d: normalize_minus(
                     Plus(d["t"].children + [
                         Times([d["ld"]] + d["l"].children + [Minus([lhs])]
                               + d["r"].children)
                     ])))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Plus([t] + [
                             normalize_minus(Times([ld, l,
                                                    Minus([ch]), r]))
                             for ch in rhs.children
                         ]), Replacement(repl_f)))
                 # A - B C in  -L B C R + L A R  (minus pushed all the way to the left)
                 repl_f = (lambda lhs: lambda d: Plus(d["t"].children + [
                     Times([d["ld"]] + d["l"].children + [lhs] + d["r"].
                           children)
                 ]))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Plus([t] + [
                             normalize_minus(Times([ld, l, ch, r]))
                             for ch in rhs.children
                         ]), Replacement(repl_f)))
                 #repl_f = (lambda lhs: lambda d: Plus(d["t"].children + [Times([simplify(to_canonical(Minus(lhs.children)))] + d["r"].children)]))(lhs_sym)
                 #pr.append( RewriteRule( Plus([t] + [
                 #Times([ Minus([ld]), l, ch, r]) if not isinstance(ch, Minus) \
                 #else Times([ l, ch.children[0], r]) \
                 #for ch in rhs.children ]),
                 #Replacement(repl_f) ) )
                 repl_f = (lambda lhs: lambda d: Plus(d["t"].children + [
                     Times([
                         simplify(to_canonical(Minus([Transpose([lhs])])))
                     ] + d["r"].children)
                 ]))(lhs_sym)
                 pr.append( RewriteRule( Plus([t] + [
                             Times([ Minus([ld]), l, simplify(to_canonical(Transpose([ch]))), r]) if not isinstance(ch, Minus) \
                                     else Times([ l, simplify(to_canonical(Transpose([ch]))), r]) \
                                     for ch in rhs.children ]),
                                 Replacement(repl_f) ) )
             elif isinstance(rhs, Times):
                 repl_f = (lambda lhs: lambda d: Times(d[
                     "l"].children + [lhs] + d["r"].children))(lhs_sym)
                 pr.append(
                     RewriteRule(Times([l] + rhs.children + [r]),
                                 Replacement(repl_f)))
                 repl_f = (lambda lhs: lambda d: Times(d[
                     "l"].children + [Transpose([lhs])] + d["r"].children)
                           )(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Times([
                             l,
                             simplify(to_canonical(Transpose([rhs]))), r
                         ]), Replacement(repl_f)))
                 # [TODO] Minus is a b*tch. Should go for -1 and remove the operator internally?
                 repl_f = (lambda lhs: lambda d: Times([
                     simplify(to_canonical(Minus([Times([lhs])])))
                 ] + d["r"].children))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Times([
                             simplify(
                                 to_canonical(
                                     Minus([Times(rhs.get_children())])))
                         ] + [r]), Replacement(repl_f)))
                 repl_f = (lambda lhs: lambda d: Times([
                     simplify(
                         to_canonical(Minus([Transpose([Times([lhs])])])))
                 ] + d["r"].children))(lhs_sym)
                 pr.append(
                     RewriteRule(
                         Times([
                             simplify(
                                 to_canonical(
                                     Minus([
                                         Transpose(
                                             [Times(rhs.get_children())])
                                     ])))
                         ] + [r]), Replacement(repl_f)))
             else:
                 pr.append(RewriteRule(rhs, Replacement(lhs_sym)))
                 new_rhs = simplify(to_canonical(Transpose([rhs])))
                 if not isOperand(new_rhs):
                     pr.append(
                         RewriteRule(
                             simplify(to_canonical(Transpose([rhs]))),
                             Replacement(Transpose([lhs_sym]))))
         else:
             pr.append(RewriteRule(rhs, Replacement(lhs)))
         rules.append(pr)
     return rules
Exemplo n.º 5
0
    def is_feasible(self):
        pme = self.pme
        linv = self.expressions

        traversal_tuples = [[0] if shape == 1 else [1, -1]
                            for shape in pme.part_tuple]
        feasible_traversals = []
        # For peeling in slingen mode
        #self.iteration_rules = []

        for traversal_dirs in itertools.product(*traversal_tuples):
            dims_to_part_shape = {}
            #for dims, shape in zip( self.operation.bound_dimensions, traversal_dirs ):
            for dims, shape in zip(self.linv_bound_dimensions, traversal_dirs):
                for dim in dims:
                    dims_to_part_shape[dim] = shape
            initial_rules = []
            final_rules = []
            trav_shape = dict()
            #for operand in self.operation.operands:
            for operand in self.linv_operands:
                trav_shape[operand.get_name()] = (
                    dims_to_part_shape[operand.get_name() + "_r"],
                    dims_to_part_shape[operand.get_name() + "_c"])
                initial_rules.extend(
                    #initial_rewrite(operand, pme.basic_partitionings[operand.get_name()], trav_shape[operand.get_name()])
                    initial_rewrite(
                        operand,
                        self.linv_operands_basic_part[operand.get_name()],
                        trav_shape[operand.get_name()]))
                final_rules.extend(
                    #final_rewrite(operand, pme.basic_partitionings[operand.get_name()], trav_shape[operand.get_name()])
                    final_rewrite(
                        operand,
                        self.linv_operands_basic_part[operand.get_name()],
                        trav_shape[operand.get_name()]))
            pre = []
            post = []

            for expr in itertools.chain(*linv):
                new = copy.deepcopy(expr)
                pre.append(simplify(to_canonical(replace(new, initial_rules))))
                new = copy.deepcopy(expr)
                post.append(simplify(to_canonical(replace(new, final_rules))))
            # check if basic init
            basic_init = True
            for expr in pre:
                lhs, rhs = expr.get_children()
                if not all( op.isZero() for op in lhs ) and not \
                        isOperand( rhs ):
                    basic_init = False
                    break
            if not basic_init:
                continue
            # check if linv and not guard -> post
            #final_status = [ replace( copy.deepcopy(expr), self.op_to_implicit ) for expr in post ]
            final_status = post
            #rules1 = []
            #rules2 = []
            #neweq = replace( copy.deepcopy(self.operation.equation), [self.pme.known_ops[-1]] )
            neweq = replace(copy.deepcopy(self.operation.equation),
                            self.pme.known_ops)
            # [FIXME] Generalize
            implies_post = True
            if not neweq in final_status:
                implies_post = False
                continue
            feasible_traversals.append((trav_shape, pre, post))
            # Store these states for use in loop peeling (LGenCode)
            #self.iteration_rules.append( (initial_rules, final_rules) )

        if len(feasible_traversals) > 1:
            print("* More than one traversal for this LoopInvariant: %d" %
                  len(feasible_traversals))
        self.traversals = feasible_traversals
        return bool(feasible_traversals)