示例#1
0
 def visit_If(self, node):
     if self.isompdirective(node.test):
         self.visit(ast.Expr(node.test))
         return self.visit(
             ast.If(ast.Constant(1, None), node.body, node.orelse))
     else:
         return self.attach_data(node)
示例#2
0
    def visit_If(self, node):
        self.generic_visit(node)

        try:
            if ast.literal_eval(node.test):
                if not metadata.get(node, OMPDirective):
                    self.update = True
                    return node.body
            else:
                if not metadata.get(node, OMPDirective):
                    self.update = True
                    return node.orelse
        except ValueError:
            # not a constant expression
            pass

        have_body = any(not isinstance(x, ast.Pass) for x in node.body)
        have_else = any(not isinstance(x, ast.Pass) for x in node.orelse)
        # If the "body" is empty but "else content" is useful, switch branches
        # and remove else content
        if not have_body and have_else:
            test = ast.UnaryOp(op=ast.Not(), operand=node.test)
            self.update = True
            return ast.If(test=test, body=node.orelse, orelse=list())
        # if neither "if" and "else" are useful, keep test if it is not pure
        elif not have_body:
            self.update = True
            if node.test in self.pure_expressions:
                return ast.Pass()
            else:
                node = ast.Expr(value=node.test)
                self.generic_visit(node)
        return node
示例#3
0
    def visit_Lambda(self, node):
        op = issimpleoperator(node)
        if op is not None:
            if mangle('operator') not in self.global_declarations:
                import_ = ast.Import(
                    [ast.alias('operator', mangle('operator'))])
                self.imports.append(import_)
                operator_module = MODULES['operator']
                self.global_declarations[mangle('operator')] = operator_module
            return ast.Attribute(
                ast.Name(mangle('operator'), ast.Load(), None, None), op,
                ast.Load())

        self.generic_visit(node)
        forged_name = "{0}_lambda{1}".format(self.prefix,
                                             len(self.lambda_functions))

        ii = self.gather(ImportedIds, node)
        ii.difference_update(self.lambda_functions)  # remove current lambdas

        binded_args = [
            ast.Name(iin, ast.Load(), None, None) for iin in sorted(ii)
        ]
        node.args.args = (
            [ast.Name(iin, ast.Param(), None, None)
             for iin in sorted(ii)] + node.args.args)
        for patternname, pattern in self.patterns.items():
            if issamelambda(pattern, node):
                proxy_call = ast.Name(patternname, ast.Load(), None, None)
                break
        else:
            duc = ExtendedDefUseChains()
            nodepattern = deepcopy(node)
            duc.visit(ast.Module([ast.Expr(nodepattern)], []))
            self.patterns[forged_name] = nodepattern, duc

            forged_fdef = ast.FunctionDef(forged_name, copy(node.args),
                                          [ast.Return(node.body)], [], None,
                                          None)
            metadata.add(forged_fdef, metadata.Local())
            self.lambda_functions.append(forged_fdef)
            self.global_declarations[forged_name] = forged_fdef
            proxy_call = ast.Name(forged_name, ast.Load(), None, None)

        if binded_args:
            if MODULES['functools'] not in self.global_declarations.values():
                import_ = ast.Import(
                    [ast.alias('functools', mangle('functools'))])
                self.imports.append(import_)
                functools_module = MODULES['functools']
                self.global_declarations[mangle(
                    'functools')] = functools_module

            return ast.Call(
                ast.Attribute(
                    ast.Name(mangle('functools'), ast.Load(), None, None),
                    "partial", ast.Load()), [proxy_call] + binded_args, [])
        else:
            return proxy_call
    def visit_Assert(self, node):
        convert_assert_node = gast.parse(
            'fluid.dygraph.dygraph_to_static.convert_operators.convert_assert({test}, {msg})'
            .format(test=ast_to_source_code(node.test),
                    msg=ast_to_source_code(node.msg)
                    if node.msg else "")).body[0].value

        return gast.Expr(value=convert_assert_node)
示例#5
0
    def visit_Assert(self, node):
        convert_assert_node = gast.parse(
            'paddle.jit.dy2static.convert_assert({test}, {msg})'.format(
                test=ast_to_source_code(node.test),
                msg=ast_to_source_code(node.msg)
                if node.msg else "")).body[0].value

        return gast.Expr(value=convert_assert_node)
 def visit_Assign(self, node):
     node.targets = [target for target in node.targets
                     if self.used_target(target)]
     if node.targets:
         return node
     self.update = True
     if node.value in self.pure_expressions:
         return ast.Pass()
     else:
         return ast.Expr(value=node.value)
示例#7
0
def create_convert_ifelse_node(return_name_ids,
                               pred,
                               true_func,
                               false_func,
                               is_if_expr=False):
    """
    Create `paddle.jit.dy2static.convert_ifelse(
            pred, true_fn, false_fn, true_args, false_args, return_vars)`
    to replace original `python if/else` statement.
    """
    def create_name_nodes(name_ids):
        if not name_ids:
            return gast.Tuple(elts=[], ctx=gast.Load())

        gast_names = [
            gast.Name(id=name_id,
                      ctx=gast.Load(),
                      annotation=None,
                      type_comment=None) for name_id in name_ids
        ]
        name_node = gast.Tuple(elts=gast_names, ctx=gast.Load())
        return name_node

    if is_if_expr:
        true_args = gast.Tuple(elts=[], ctx=gast.Load())
        false_args = gast.Tuple(elts=[], ctx=gast.Load())
        true_func_source = "lambda : {}".format(ast_to_source_code(true_func))
        false_func_source = "lambda : {}".format(
            ast_to_source_code(false_func))
    else:
        true_args = gast.Tuple(elts=true_func.args.args, ctx=gast.Load())
        false_args = gast.Tuple(elts=false_func.args.args, ctx=gast.Load())
        true_func_source = true_func.name
        false_func_source = false_func.name

    return_vars = create_name_nodes(return_name_ids)

    convert_ifelse_layer = gast.parse(
        'paddle.jit.dy2static.convert_ifelse('
        '{pred}, {true_fn}, {false_fn}, {true_args}, {false_args}, {return_vars})'
        .format(pred=ast_to_source_code(pred),
                true_fn=true_func_source,
                false_fn=false_func_source,
                true_args=ast_to_source_code(true_args),
                false_args=ast_to_source_code(false_args),
                return_vars=ast_to_source_code(return_vars))).body[0].value

    if return_name_ids:
        _, cond_node = create_assign_node(return_name_ids,
                                          convert_ifelse_layer)
    else:  # No variables can be returned if no assign statement in if.body.
        cond_node = gast.Expr(value=convert_ifelse_layer)

    return cond_node
示例#8
0
 def visit_Print(self, node):
     self.generic_visit(node)
     for n in node.values:
         n.ctx = gast.Param()
     call_node = gast.Call(func=gast.Name('print', gast.Load(), None),
                           args=node.values,
                           keywords=[])
     anno.setanno(call_node.func, 'live_val', print)
     anno.setanno(call_node.func, 'fqn', 'print')
     anno.setanno(call_node, 'args_scope', anno.getanno(node, 'args_scope'))
     node = gast.Expr(call_node)
     return node
示例#9
0
 def visit_Assert(self, node):
     if not self.static_analysis_visitor.is_tensor_node(node.test):
         return node
     cast_node = gast.Call(
         func=gast.parse("fluid.layers.cast").body[0].value,
         args=[node.test, gast.Constant(value="bool", kind=None)],
         keywords=[])
     assert_node = gast.Call(
         func=gast.parse("fluid.layers.Assert").body[0].value,
         args=[cast_node],
         keywords=[])
     return gast.Expr(value=assert_node)
示例#10
0
def test_statement_replace():
    def f(body):
        body

    body = [
        gast.Expr(value=gast.Name(id=var, ctx=gast.Load(), annotation=None))
        for var in 'xy'
    ]
    new_body = template.replace(f, body=body)
    assert len(new_body) == 2
    assert isinstance(new_body[0], gast.Expr)
    compile_.compile_function(_wrap(new_body))
示例#11
0
    def visit_Return(self, node):
        """Intercepts return statements.

    Args:
      node: An `ast.AST` node representing the `return` statement to convert.

    Returns:
      node: A node representing the result.
    """
        node = templates.replace_as_expression(
            '_tfp_autobatching_context_.return_(value)',
            value=self._to_reference(node.value))
        return gast.Expr(node)
示例#12
0
    def visit_AnyComp(self, node, comp_type, *path):
        self.update = True
        node.elt = self.visit(node.elt)
        name = "{0}_comprehension{1}".format(comp_type, self.count)
        self.count += 1
        args = self.gather(ImportedIds, node)
        self.count_iter = 0

        starget = "__target"
        body = reduce(self.nest_reducer,
                      reversed(node.generators),
                      ast.Expr(
                          ast.Call(
                              reduce(lambda x, y: ast.Attribute(x, y,
                                                                ast.Load()),
                                     path[1:],
                                     ast.Name(path[0], ast.Load(),
                                              None, None)),
                              [ast.Name(starget, ast.Load(), None, None),
                               node.elt],
                              [],
                              )
                          )
                      )
        # add extra metadata to this node
        metadata.add(body, metadata.Comprehension(starget))
        init = ast.Assign(
            [ast.Name(starget, ast.Store(), None, None)],
            ast.Call(
                ast.Attribute(
                    ast.Name('builtins', ast.Load(), None, None),
                    comp_type,
                    ast.Load()
                    ),
                [], [],)
            )
        result = ast.Return(ast.Name(starget, ast.Load(), None, None))
        sargs = [ast.Name(arg, ast.Param(), None, None) for arg in args]
        fd = ast.FunctionDef(name,
                             ast.arguments(sargs, [], None, [], [], None, []),
                             [init, body, result],
                             [], None, None)
        metadata.add(fd, metadata.Local())
        self.ctx.module.body.append(fd)
        return ast.Call(
            ast.Name(name, ast.Load(), None, None),
            [ast.Name(arg.id, ast.Load(), None, None) for arg in sargs],
            [],
            )  # no sharing !
示例#13
0
    def dispatch(self, tree):
        """Dispatcher function, dispatching tree type T to method _T."""
        # display omp directive in python dump
        for omp in metadata.get(tree, openmp.OMPDirective):
            deps = list()
            for dep in omp.deps:
                old_file = self.f
                self.f = io.StringIO()
                self.dispatch(dep)
                deps.append(self.f.getvalue())
                self.f = old_file
            directive = omp.s.format(*deps)
            self._Expr(ast.Expr(ast.Constant(directive, None)))

        if isinstance(tree, list):
            for t in tree:
                self.dispatch(t)
            return
        meth = getattr(self, "_" + tree.__class__.__name__)
        meth(tree)
示例#14
0
    def visit_GeneratorExp(self, node):
        self.update = True
        node.elt = self.visit(node.elt)
        name = "generator_expression{0}".format(self.count)
        self.count += 1
        args = self.passmanager.gather(ImportedIds, node, self.ctx)
        self.count_iter = 0

        body = reduce(self.nest_reducer, reversed(node.generators),
                      ast.Expr(ast.Yield(node.elt)))

        sargs = [ast.Name(arg, ast.Param(), None) for arg in args]
        fd = ast.FunctionDef(name, ast.arguments(sargs, None, [], [], None,
                                                 []), [body], [], None)
        self.ctx.module.body.append(fd)
        return ast.Call(
            ast.Name(name, ast.Load(), None),
            [ast.Name(arg.id, ast.Load(), None) for arg in sargs],
            [],
        )  # no sharing !
示例#15
0
def create_cond_node(return_name_ids,
                     pred,
                     true_func,
                     false_func,
                     is_if_expr=False):
    """
    Create `fluid.layers.cond(pred, true_fn, false_fn)` to replace
    original `python if/else` statement.
    """
    def create_lambda_node(func_or_expr_node, is_if_expr=False):
        body = func_or_expr_node
        if not is_if_expr:
            body = gast.Call(func=gast.Name(id=func_or_expr_node.name,
                                            ctx=gast.Load(),
                                            annotation=None,
                                            type_comment=None),
                             args=[func_or_expr_node.args],
                             keywords=[])

        lambda_node = gast.Lambda(args=gast.arguments(args=[],
                                                      posonlyargs=[],
                                                      vararg=None,
                                                      kwonlyargs=[],
                                                      kw_defaults=None,
                                                      kwarg=None,
                                                      defaults=[]),
                                  body=body)
        return lambda_node

    cond_api = gast.parse('fluid.layers.cond').body[0].value
    true_func_lambda = create_lambda_node(true_func, is_if_expr)
    false_func_lambda = create_lambda_node(false_func, is_if_expr)
    cond_layer = gast.Call(func=cond_api,
                           args=[pred, true_func_lambda, false_func_lambda],
                           keywords=[])
    if return_name_ids:
        _, cond_node = create_assign_node(return_name_ids, cond_layer)
    else:  # No variables can be returned if no assign statement in if.body.
        cond_node = gast.Expr(value=cond_layer)

    return cond_node
 def test_usub(self):
     orig_ast = gast.ast_to_gast(ast.parse("-3"))
     target_ast = gast.Module(
         body=[gast.Expr(value=gast.Constant(value=-3, kind=None))],
         type_ignores=[])
     assert compare_ast(self.canonicalizer.visit(orig_ast), target_ast)
示例#17
0
import gast

from .recompile import compile_function, code_to_ast


def pushmask(mask_expr):
    return gast.Expr(
        gast.Call(
            gast.Attribute(gast.Name('matchbox', gast.Load(), None),
                           gast.Name('push_execution_mask', gast.Load(), None),
                           gast.Load()), [mask_expr], []))


popmask = gast.Expr(
    gast.Call(
        gast.Attribute(gast.Name('matchbox', gast.Load(), None),
                       gast.Name('pop_execution_mask', gast.Load(), None),
                       gast.Load()), [], []))


def any_active(mask_expr):
    return gast.Call(
        gast.Attribute(  # TODO any over dim 0
            mask_expr, gast.Name('any', gast.Load(), None), gast.Load()),
        [],
        [])


class FuseAttributes(gast.NodeTransformer):
    '''Transform foo.bar to foo_DOT_bar'''
    def visit_Attribute(self, node):
示例#18
0
def pushmask(mask_expr):
    return gast.Expr(
        gast.Call(
            gast.Attribute(gast.Name('matchbox', gast.Load(), None),
                           gast.Name('push_execution_mask', gast.Load(), None),
                           gast.Load()), [mask_expr], []))
示例#19
0
 def visit_Print(self, node):
     var = self._get_print_var(node)
     print_call_node = self._construct_print_node(var)
     return gast.Expr(value=print_call_node)
示例#20
0
 def visit_Print(self, node):
     convert_print_node = self._create_print_node(node.values)
     return gast.Expr(value=convert_print_node)
示例#21
0
    def visit_If(self, node):
        if node.test not in self.static_expressions:
            return self.generic_visit(node)

        imported_ids = self.gather(ImportedIds, node)

        assigned_ids_left = self.escaping_ids(node, node.body)
        assigned_ids_right = self.escaping_ids(node, node.orelse)
        assigned_ids_both = assigned_ids_left.union(assigned_ids_right)

        imported_ids.update(i for i in assigned_ids_left
                            if i not in assigned_ids_right)
        imported_ids.update(i for i in assigned_ids_right
                            if i not in assigned_ids_left)
        imported_ids = sorted(imported_ids)

        assigned_ids = sorted(assigned_ids_both)

        fbody = self.make_fake(node.body)
        true_has_return = self.gather(HasReturn, fbody)
        true_has_break = self.gather(HasBreak, fbody)
        true_has_cont = self.gather(HasContinue, fbody)

        felse = self.make_fake(node.orelse)
        false_has_return = self.gather(HasReturn, felse)
        false_has_break = self.gather(HasBreak, felse)
        false_has_cont = self.gather(HasContinue, felse)

        has_return = true_has_return or false_has_return
        has_break = true_has_break or false_has_break
        has_cont = true_has_cont or false_has_cont

        self.generic_visit(node)

        func_true = outline(self.true_name(), imported_ids, assigned_ids,
                            node.body, has_return, has_break, has_cont)
        func_false = outline(self.false_name(), imported_ids, assigned_ids,
                             node.orelse, has_return, has_break, has_cont)
        self.new_functions.extend((func_true, func_false))

        actual_call = self.make_dispatcher(node.test,
                                           func_true, func_false, imported_ids)

        # variable modified within the static_if
        expected_return = [ast.Name(ii, ast.Store(), None, None)
                           for ii in assigned_ids]

        self.update = True

        # name for various variables resulting from the static_if
        n = len(self.new_functions)
        status_n = "$status{}".format(n)
        return_n = "$return{}".format(n)
        cont_n = "$cont{}".format(n)

        if has_return:
            cfg = self.cfgs[-1]
            always_return = all(isinstance(x, (ast.Return, ast.Yield))
                                for x in cfg[node])
            always_return &= true_has_return and false_has_return

            fast_return = [ast.Name(status_n, ast.Store(), None, None),
                           ast.Name(return_n, ast.Store(), None, None),
                           ast.Name(cont_n, ast.Store(), None, None)]

            if always_return:
                return [ast.Assign([ast.Tuple(fast_return, ast.Store())],
                                   actual_call, None),
                        ast.Return(ast.Name(return_n, ast.Load(), None, None))]
            else:
                cont_ass = self.make_control_flow_handlers(cont_n, status_n,
                                                           expected_return,
                                                           has_cont, has_break)

                cmpr = ast.Compare(ast.Name(status_n, ast.Load(), None, None),
                                   [ast.Eq()], [ast.Constant(EARLY_RET, None)])
                return [ast.Assign([ast.Tuple(fast_return, ast.Store())],
                                   actual_call, None),
                        ast.If(cmpr,
                               [ast.Return(ast.Name(return_n, ast.Load(),
                                                    None, None))],
                               cont_ass)]
        elif has_break or has_cont:
            cont_ass = self.make_control_flow_handlers(cont_n, status_n,
                                                       expected_return,
                                                       has_cont, has_break)

            fast_return = [ast.Name(status_n, ast.Store(), None, None),
                           ast.Name(cont_n, ast.Store(), None, None)]
            return [ast.Assign([ast.Tuple(fast_return, ast.Store())],
                               actual_call, None)] + cont_ass
        elif expected_return:
            return ast.Assign([ast.Tuple(expected_return, ast.Store())],
                              actual_call, None)
        else:
            return ast.Expr(actual_call)
示例#22
0
    def visit_If(self, node):
        self.generic_visit(node)
        if node.test not in self.static_expressions:
            return node

        imported_ids = self.passmanager.gather(ImportedIds, node, self.ctx)

        assigned_ids_left = set(
            self.passmanager.gather(IsAssigned, self.make_fake(node.body),
                                    self.ctx).keys())
        assigned_ids_right = set(
            self.passmanager.gather(IsAssigned, self.make_fake(node.orelse),
                                    self.ctx).keys())
        assigned_ids_both = assigned_ids_left.union(assigned_ids_right)

        imported_ids.update(i for i in assigned_ids_left
                            if i not in assigned_ids_right)
        imported_ids.update(i for i in assigned_ids_right
                            if i not in assigned_ids_left)
        imported_ids = sorted(imported_ids)

        assigned_ids = sorted(assigned_ids_both)

        true_has_return = self.passmanager.gather(HasReturn,
                                                  self.make_fake(node.body),
                                                  self.ctx)
        false_has_return = self.passmanager.gather(HasReturn,
                                                   self.make_fake(node.orelse),
                                                   self.ctx)

        has_return = true_has_return or false_has_return

        func_true = outline(self.true_name(), imported_ids, assigned_ids,
                            node.body, has_return)
        func_false = outline(self.false_name(), imported_ids, assigned_ids,
                             node.orelse, has_return)
        self.new_functions.extend((func_true, func_false))

        actual_call = self.make_dispatcher(node.test, func_true, func_false,
                                           imported_ids)

        expected_return = [
            ast.Name(ii, ast.Load(), None) for ii in assigned_ids
        ]

        if has_return:
            n = len(self.new_functions)
            fast_return = [
                ast.Name("$status{}".format(n), ast.Load(), None),
                ast.Name("$return{}".format(n), ast.Load(), None),
                ast.Name("$cont{}".format(n), ast.Load(), None)
            ]

            if expected_return:
                cont_ass = [
                    ast.Assign([ast.Tuple(expected_return, ast.Store())],
                               ast.Name("$cont{}".format(n), ast.Load(), None))
                ]
            else:
                cont_ass = []

            return [
                ast.Assign([ast.Tuple(fast_return, ast.Store())], actual_call),
                ast.If(ast.Name("$status{}".format(n), ast.Load(), None), [
                    ast.Return(
                        ast.Name("$return{}".format(n), ast.Load(), None))
                ], cont_ass)
            ]
        elif expected_return:
            return ast.Assign([ast.Tuple(expected_return, ast.Store())],
                              actual_call)
        else:
            return ast.Expr(actual_call)
示例#23
0
 def test_usub(self):
     orig_ast = gast.ast_to_gast(ast.parse("-3"))
     target_ast = gast.Module(body=[gast.Expr(value=gast.Num(n=-3))])
     assert compare_ast(self.canonicalizer.visit(orig_ast), target_ast)
 def build(v):
     return gast.Expr(value=gast.Call(
         func=make_name("print"), args=[v], keywords=[]))