Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Publish to PyPI on Release

on:
release:
types: [created] # 当有新Release创建时触发
types: [created]

jobs:
release:
Expand Down
87 changes: 87 additions & 0 deletions benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from amrita_sense.instructions.batch import BATCH_RUN
from amrita_sense.instructions.func_block import FUN_BLOCK
from amrita_sense.instructions.loop.while_clause import WHILE
from amrita_sense.instructions.native import NATIVE_DO, NATIVE_IF, NATIVE_WHILE
from amrita_sense.instructions.workfl_ctrl import NOP
from amrita_sense.utils import TimeInsighter

Expand Down Expand Up @@ -388,6 +389,92 @@ def bench_batch_run_forks() -> Result:
)


# Native instruction benchmarks


@benchmark
def bench_native_if_chain() -> Result:
"""Native-IF chain (100 ELIF)"""
depth = 100

@Node()
def _body() -> None:
pass

conds = [
NodeType(lambda: False, wrap_to_async=False, address_able=False, tag=None)
for _ in range(depth)
]
conds[-1] = NodeType(
lambda: True, wrap_to_async=False, address_able=False, tag=None
)

chain = NATIVE_IF(conds[0], _body) # type: ignore[arg-type]
for c in conds[1:]:
chain = chain.ELIF(c, _body) # type: ignore[arg-type]
chain = chain.ELSE(_body).extract()

rendered, cs = _sense_compile(chain)
es = _sense_exec(rendered)

return Result(
"Native-IF (100 ELIF)",
sense_compile_s=cs,
sense_exec_s=es,
extra={"depth": depth},
)


@benchmark
def bench_native_while_tight() -> Result:
"""Native-WHILE tight loop"""
counter = [0]

@Node()
def body() -> None:
counter[0] += 1

@Node()
def check() -> bool:
return counter[0] < LOOP_ITERS

wf = NATIVE_WHILE(check).ACTION(body).extract()
rendered, cs = _sense_compile(wf)
es = _sense_exec(rendered)

return Result(
"Native-WHILE tight",
sense_compile_s=cs,
sense_exec_s=es,
extra={"iters": LOOP_ITERS},
)


@benchmark
def bench_native_do_tight() -> Result:
"""Native-DO tight loop"""
counter = [0]

@Node()
def body() -> None:
counter[0] += 1

@Node()
def check() -> bool:
return counter[0] < LOOP_ITERS

wf = NATIVE_DO(body).WHILE(check).extract()
rendered, cs = _sense_compile(wf)
es = _sense_exec(rendered)

return Result(
"Native-DO tight",
sense_compile_s=cs,
sense_exec_s=es,
extra={"iters": LOOP_ITERS},
)


# Entry point

if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions demos/16_subgraph_isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from amrita_sense import ALIAS, NOP, Node, WorkflowInterpreter

# --- Sub-workflow ---
### Sub-workflow ###


@Node()
Expand All @@ -33,7 +33,7 @@ async def sub_step2() -> None:
sub_comp = sub_start >> sub_step1 >> sub_step2 >> ALIAS(NOP, "done")


# --- Main node ---
### Main node ###


@Node()
Expand Down
6 changes: 3 additions & 3 deletions demos/20_batch_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from amrita_sense import Node, WorkflowInterpreter
from amrita_sense.instructions.batch import BATCH_RUN

# --- Parallel bare nodes ---
### Parallel bare nodes ###


@Node()
Expand All @@ -30,7 +30,7 @@ async def fetch_products() -> None:
print(" [products] fetched")


# --- Parallel subgraphs ---
### Parallel subgraphs ###


@Node()
Expand All @@ -53,7 +53,7 @@ async def transform() -> None:
print(" [transform] done")


# --- fail_fast demo ---
### fail_fast demo ###


@Node()
Expand Down
107 changes: 107 additions & 0 deletions demos/21_native_if.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""21_native_if.py — NATIVE_IF / NATIVE_WHILE / NATIVE_DO demo.

Usage:
python demos/21_native_if.py
"""

import asyncio

from amrita_sense import Node, WorkflowInterpreter
from amrita_sense.instructions.native import NATIVE_DO, NATIVE_IF, NATIVE_WHILE


@Node()
async def cond_true() -> bool:
print(" cond → True")
return True


@Node()
async def cond_false() -> bool:
print(" cond → False")
return False


@Node()
async def if_body() -> None:
print(" IF body executed")


@Node()
async def else_body() -> None:
print(" ELSE body executed")


@Node()
async def while_body() -> None:
print(" WHILE body iteration")


@Node()
async def do_body() -> None:
print(" DO body iteration")


async def main() -> None:
### NATIVE_IF single node ###
print("=== NATIVE_IF (condition True) ===")
comp = NATIVE_IF(cond_true, if_body).ELSE(else_body)
await WorkflowInterpreter(comp.extract().render()).run()

print("\n=== NATIVE_IF (condition False → ELSE) ===")
comp = NATIVE_IF(cond_false, if_body).ELSE(else_body)
await WorkflowInterpreter(comp.extract().render()).run()

### NATIVE_WHILE single node (1 iteration then false) ###
print("\n=== NATIVE_WHILE (1 iteration) ===")
counter = [0]

@Node()
async def wh_cond() -> bool:
counter[0] += 1
print(f" WHILE cond iteration {counter[0]}")
return counter[0] <= 1

@Node()
async def wh_body() -> None:
print(f" WHILE body iteration {counter[0]}")

comp = NATIVE_WHILE(wh_cond).ACTION(wh_body)
await WorkflowInterpreter(comp.extract().render()).run()

### NATIVE_DO single node ###
print("\n=== NATIVE_DO (1 iteration) ===")
counter2 = [0]

@Node()
async def do_cond() -> bool:
counter2[0] += 1
print(f" DO cond iteration {counter2[0]}")
return counter2[0] < 1 # execute twice then stop

@Node()
async def do_bd() -> None:
print(f" DO body iteration {counter2[0] + 1}")

comp = NATIVE_DO(do_bd).WHILE(do_cond)
await WorkflowInterpreter(comp.extract().render()).run()

### NATIVE_IF with NodeCompose body (bubble) ###
print("\n=== NATIVE_IF bubble body ===")

@Node()
async def bubble_step_a() -> None:
print(" bubble step A")

@Node()
async def bubble_step_b() -> None:
print(" bubble step B")

comp = NATIVE_IF(cond_true, bubble_step_a >> bubble_step_b)
await WorkflowInterpreter(comp.extract().render()).run()

print("\n=== ALL DONE ===")


if __name__ == "__main__":
asyncio.run(main())
18 changes: 16 additions & 2 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ export default withMermaid({
text: "External Interrupt",
link: "/guide/advanced/external_interrupt",
},
{
text: "Native Control Flow",
link: "/guide/advanced/native_control_flow",
},
{
text: "Built-in Instruction Set",
items: [
Expand Down Expand Up @@ -182,6 +186,10 @@ export default withMermaid({
text: "Context Snapshot & Interrupt Transfer (PUSH_CONTEXT/INTERRUPT_INTO)",
link: "/guide/advanced/built-in_instruction_set/context_clause",
},
{
text: "Native Instructions (NATIVE_IF/WHILE/DO/BREAK_LOOP)",
link: "/guide/advanced/built-in_instruction_set/native_instructions",
},
],
},
{ text: "Custom Nodes", link: "/guide/advanced/custom_node" },
Expand Down Expand Up @@ -223,7 +231,6 @@ export default withMermaid({
text: "REPL Debugging",
link: "/guide/practice/repl-debugging",
},
{ text: "Under Construction..." },
],
},
{
Expand Down Expand Up @@ -333,6 +340,10 @@ export default withMermaid({
text: "外部中断",
link: "/zh/guide/advanced/external_interrupt",
},
{
text: "原生控制流",
link: "/zh/guide/advanced/native_control_flow",
},
{
text: "内置指令集",
items: [
Expand Down Expand Up @@ -360,6 +371,10 @@ export default withMermaid({
text: "上下文与中断转移 (PUSH_CONTEXT/INTERRUPT_INTO)",
link: "/zh/guide/advanced/built-in_instruction_set/context_clause",
},
{
text: "原生特性指令 (NATIVE_IF/WHILE/DO/BREAK_LOOP)",
link: "/zh/guide/advanced/built-in_instruction_set/native_instructions",
},
],
},
{ text: "自定义节点", link: "/zh/guide/advanced/custom_node" },
Expand Down Expand Up @@ -401,7 +416,6 @@ export default withMermaid({
text: "REPL 调试",
link: "/zh/guide/practice/repl-debugging",
},
{ text: "正在施工中......" },
],
},
{
Expand Down
4 changes: 2 additions & 2 deletions docs/.vitepress/theme/var.css
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@
--vp-custom-block-danger-border: rgba(224, 85, 85, 0.3);

/* Status colors — dark */
--vp-c-tip-1: #e6C17A;
--vp-c-tip-1: #e6c17a;
--vp-c-tip-2: #d4a84d;
--vp-c-tip-3: #c8a454;
--vp-c-tip-soft: rgba(230, 193, 122, 0.12);

--vp-c-warning-1: #f0d18a;
--vp-c-warning-2: #e6C17A;
--vp-c-warning-2: #e6c17a;
--vp-c-warning-3: #d4a84d;
--vp-c-warning-soft: rgba(230, 193, 122, 0.12);

Expand Down
Loading
Loading