Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

[Compat][3.11] support for-loop #371

Merged
merged 21 commits into from
Sep 5, 2023

Conversation

zrr1999
Copy link
Member

@zrr1999 zrr1999 commented Sep 3, 2023

  1. 前移 _current_line 初始化为 -1 的语句,使得当 get_instructions 函数中发生错误时依然可以正确返回报错栈。
  2. 实现 gen_jump、gen_pop_jump,简化后期适配操作。
  3. fix _break_graph_in_for_loop in python3.11, 将以前固定的jump(大多数为绝对跳转),改为根据方向调整jump指令(python3.11新指令)。
  4. 修复 relocate_jump_target,使其可以正确计算JUMP_BACKWARD的参数。
  5. 启用如下单测
    • test_12_for_loop ❌ -> ✅
    • test_15_slice ❌ -> ✅
    • test_21_global ❌ -> ✅
    • test_enumerate ❌ -> ✅
    • test_inplace_api ❌ -> ✅
    • test_range ❌ -> ✅
    • test_resnet50_backward ❌ -> ✅
    • test_side_effects 🚧 -> ✅

@paddle-bot
Copy link

paddle-bot bot commented Sep 3, 2023

Thanks for your contribution!

@paddle-bot paddle-bot bot added the contributor External developers label Sep 3, 2023
@zrr1999 zrr1999 changed the title Py3.11 bg jump [Compat][3.11] support jump breakgraph Sep 4, 2023
@zrr1999 zrr1999 marked this pull request as ready for review September 4, 2023 15:00
@zrr1999 zrr1999 requested review from SigureMo and gouzil September 4, 2023 15:00
@SigureMo SigureMo changed the title [Compat][3.11] support jump breakgraph [Compat][3.11] support for-loop Sep 5, 2023
Comment on lines 2102 to 2109
if sys.version_info >= (3, 11):
jump_if_break = self._graph.pycode_gen._add_instr(
"POP_JUMP_FORWARD_IF_FALSE"
)
else:
jump_if_break = self._graph.pycode_gen._add_instr(
"POP_JUMP_IF_FALSE"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是否可以直接用 gen_pop_jump 呢?

Comment on lines 188 to 198
elif instr.opname == "JUMP_BACKWARD":
new_arg = instr.offset - jump_target + 2
if new_arg < 0:
# NOTE(zrr1999): in Python 3.11, JUMP_ABSOLUTE is removed, so we need to use JUMP_FORWARD instead,
# but in for loop breakgraph, we reuse JUMP_BACKWARD to jump forward, so we need to change it to JUMP_FORWARD.
instr.opname = "JUMP_FORWARD"
instr.opcode = dis.opmap["JUMP_FORWARD"]
new_arg = jump_target - instr.offset - 2
else:
# other REL_JUMP, such as JUMP_FORWARD, FOR_ITER
new_arg = jump_target - instr.offset - 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是否可以写个函数来自动修正 JUMP 呢(Callable[[Instruction], Instruction])?包括 BACKWARD -> FORWARD 和 FORWARD -> BACKWARD

这段逻辑就可以封装起来了


# 7. add JUMP_ABSOLUTE to FOR_ITER
self._graph.pycode_gen._add_instr("JUMP_ABSOLUTE", jump_to=for_iter)
self._graph.pycode_gen.gen_jump(cur_instr, for_iter)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cur_instr 只是栈分析时候使用的临时变量,这样传可能不太对

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里一定是往回跳(跳回FOR_ITER)

break_jump = pycode_gen._add_instr(
"JUMP_ABSOLUTE", jump_to=out_loop_instr
)
cur_instr = self._instructions[self._lasti]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个不就是for_iter这个输入吗

"JUMP_ABSOLUTE", jump_to=out_loop_instr
)
cur_instr = self._instructions[self._lasti]
pycode_gen.gen_jump(cur_instr, out_loop_instr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里jump的起点也不是self._instructions[self._lasti]吧,应该是我们生成的最新代码的起点
如果是这样,那么起点和终点应该都到 pycode gen 里面拿啊,怎么去 self._instruction 里面拿,那个是原始的code啊

nop_for_continue = pycode_gen._add_instr("NOP")
jump = pycode_gen.gen_jump(cur_instr, for_iter_instr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

@@ -871,6 +871,38 @@ def gen_swap(self, n):
else:
raise NotImplementedError("swap is not supported before python3.11")

def gen_jump(self, instr: Instruction, jump_to: Instruction) -> Instruction:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要传instr吧?没有用而且是错的,因为跳转起点不应该是待会要插入的jump语句吗?那么应该用下一个待插入的位置的offset来比吧?


def gen_pop_jump(
self, instr: Instruction, jump_to: Instruction, *, suffix: str = ""
):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

Comment on lines 173 to 174
instr.opname = "JUMP_BACKWARD"
instr.opcode = dis.opmap["JUMP_BACKWARD"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这貌似不太对?这里是不是应该将 FORWARD 改成 BACKWARD,BACKWARD 改成 FORWARD?

另外 else 分支是不是不用动?

@@ -871,6 +871,35 @@ def gen_swap(self, n):
else:
raise NotImplementedError("swap is not supported before python3.11")

def gen_forward_jump(self, jump_to: Instruction) -> Instruction:
return self._add_instr("JUMP_BACKWARD", jump_to=jump_to)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emmm?FORWARD?

Copy link
Collaborator

@feifei-111 feifei-111 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@SigureMo SigureMo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTMeow 🐾

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
contributor External developers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants