124124DESCRIPTOR_PORTABLE_KERNEL_BUFFER_LIMIT = 31
125125DESCRIPTOR_SHARED_SCRATCH_SPILL_THRESHOLD_BYTES = 1024
126126DESCRIPTOR_SHARED_SCRATCH_BUDGET_BYTES = 12 * 1024
127- MAMBA3_BWD_REPLAY_CHECKPOINT_INTERVAL = 64
127+ MAMBA3_BWD_REPLAY_CHECKPOINT_INTERVAL = 8
128128M2RNN_BWD_REPLAY_CHECKPOINT_INTERVAL = 1
129129_DESCRIPTOR_ROOT_READS_MARKER = "cppmega_path_c_root_reads"
130130_DESCRIPTOR_ROOT_WRITES_MARKER = "cppmega_path_c_root_writes"
@@ -430,6 +430,7 @@ class PathCDescriptorScheduleStageGroup:
430430 active_node_names: tuple[str, ...]
431431 stage_suffix: str
432432 row_dispatch_mode: str
433+ rows_per_kernel_launch: int
433434 reason: str
434435
435436
@@ -488,6 +489,13 @@ def _path_c_descriptor_stage_node_op_name(node: Any) -> str:
488489 return str(getattr(node, "op_name", ""))
489490
490491
492+ def _path_c_descriptor_stage_rows_per_kernel_launch_for_node(node: Any) -> int:
493+ op_name = _path_c_descriptor_stage_node_op_name(node)
494+ if op_name in {"attention_qkv_projection_bwd", "mamba3_mimo_bwd"}:
495+ return 1
496+ return DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH
497+
498+
491499def _path_c_descriptor_stage_append(
492500 groups: list[PathCDescriptorScheduleStageGroup],
493501 *,
@@ -496,6 +504,7 @@ def _path_c_descriptor_stage_append(
496504 active_node_names: Sequence[str],
497505 reason: str,
498506 row_dispatch_mode: str = DESCRIPTOR_ROW_DISPATCH_LAUNCHER_CHUNKS,
507+ rows_per_kernel_launch: int = DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH,
499508) -> None:
500509 names = tuple(str(name) for name in active_node_names if str(name))
501510 if not names:
@@ -510,6 +519,9 @@ def _path_c_descriptor_stage_append(
510519 active_node_names=names,
511520 stage_suffix=f"{prefix}{stage_index}",
512521 row_dispatch_mode=validated_mode,
522+ rows_per_kernel_launch=_validated_rows_per_kernel_launch(
523+ rows_per_kernel_launch
524+ ),
513525 reason=reason,
514526 )
515527 )
@@ -592,6 +604,11 @@ def plan_path_c_descriptor_stage_groups(
592604 stage_index=backward_index,
593605 active_node_names=(name,),
594606 reason=f"descriptor_isolates_backward_{op_name}_fragment",
607+ rows_per_kernel_launch=(
608+ _path_c_descriptor_stage_rows_per_kernel_launch_for_node(
609+ node
610+ )
611+ ),
595612 )
596613 backward_consumed.add(name)
597614 backward_index += 1
@@ -606,6 +623,9 @@ def plan_path_c_descriptor_stage_groups(
606623 stage_index=backward_index,
607624 active_node_names=(name,),
608625 reason="descriptor_keeps_backward_block_as_generated_stage",
626+ rows_per_kernel_launch=(
627+ _path_c_descriptor_stage_rows_per_kernel_launch_for_node(node)
628+ ),
609629 )
610630 backward_consumed.add(name)
611631 backward_index += 1
@@ -666,6 +686,7 @@ def make_path_c_descriptor_stage_schedule_template(
666686 active_node_names: Sequence[str] | None = None,
667687 stage_suffix: str = "",
668688 row_dispatch_mode: str = DESCRIPTOR_ROW_DISPATCH_LAUNCHER_CHUNKS,
689+ rows_per_kernel_launch: int = DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH,
669690) -> Callable[[Any], Any]:
670691 """Build a generated stage template with the train-block ABI contract.
671692
@@ -697,6 +718,7 @@ def make_path_c_descriptor_stage_schedule_template(
697718 ),
698719 max_rows_per_launch=schedule_target.max_rows_per_launch,
699720 row_dispatch_mode=row_dispatch_mode,
721+ rows_per_kernel_launch=rows_per_kernel_launch,
700722 execution_stage=execution_stage,
701723 active_node_names=active_node_names,
702724 ),
@@ -728,6 +750,7 @@ def path_c_descriptor_stage_prim_funcs(
728750 active_node_names=group.active_node_names,
729751 stage_suffix=group.stage_suffix,
730752 row_dispatch_mode=group.row_dispatch_mode,
753+ rows_per_kernel_launch=group.rows_per_kernel_launch,
731754 )
732755 for group in stage_groups
733756 )
@@ -1317,6 +1340,7 @@ def make_path_c_descriptor_schedule_template(
13171340 train_step_output_abi: bool = False,
13181341 max_rows_per_launch: int | None = None,
13191342 row_dispatch_mode: str = DESCRIPTOR_DEFAULT_ROW_DISPATCH_MODE,
1343+ rows_per_kernel_launch: int = DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH,
13201344 execution_stage: str = DESCRIPTOR_EXECUTION_STAGE_ALL,
13211345 active_node_names: Sequence[str] | None = None,
13221346) -> Callable[[Any], Any]:
@@ -1337,6 +1361,9 @@ def make_path_c_descriptor_schedule_template(
13371361 max_rows_per_launch
13381362 )
13391363 validated_row_dispatch_mode = _validated_row_dispatch_mode(row_dispatch_mode)
1364+ validated_rows_per_kernel_launch = _validated_rows_per_kernel_launch(
1365+ rows_per_kernel_launch
1366+ )
13401367 validated_execution_stage = _validated_execution_stage(execution_stage)
13411368 active_node_names_tuple = (
13421369 tuple(str(name) for name in active_node_names)
@@ -1357,6 +1384,7 @@ def descriptor_schedule_template(template_region: Any) -> Any:
13571384 train_step_output_abi=bool(train_step_output_abi),
13581385 max_rows_per_launch=validated_max_rows_per_launch,
13591386 row_dispatch_mode=validated_row_dispatch_mode,
1387+ rows_per_kernel_launch=validated_rows_per_kernel_launch,
13601388 execution_stage=validated_execution_stage,
13611389 active_node_names=active_node_names_tuple,
13621390 )
@@ -1383,6 +1411,9 @@ def descriptor_schedule_template(template_region: Any) -> Any:
13831411 descriptor_schedule_metadata._cppmega_path_c_row_dispatch_mode = (
13841412 validated_row_dispatch_mode
13851413 )
1414+ descriptor_schedule_metadata._cppmega_path_c_rows_per_kernel_launch = (
1415+ validated_rows_per_kernel_launch
1416+ )
13861417 descriptor_schedule_metadata._cppmega_path_c_execution_stage = (
13871418 validated_execution_stage
13881419 )
@@ -1461,6 +1492,7 @@ def build_path_c_descriptor_prim_func(
14611492 train_step_output_abi: bool = False,
14621493 max_rows_per_launch: int | None = None,
14631494 row_dispatch_mode: str = DESCRIPTOR_DEFAULT_ROW_DISPATCH_MODE,
1495+ rows_per_kernel_launch: int = DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH,
14641496 execution_stage: str = DESCRIPTOR_EXECUTION_STAGE_ALL,
14651497 active_node_names: Sequence[str] | None = None,
14661498) -> Any:
@@ -1486,6 +1518,9 @@ def build_path_c_descriptor_prim_func(
14861518 max_rows_per_launch
14871519 )
14881520 validated_row_dispatch_mode = _validated_row_dispatch_mode(row_dispatch_mode)
1521+ validated_rows_per_kernel_launch = _validated_rows_per_kernel_launch(
1522+ rows_per_kernel_launch
1523+ )
14891524 validated_execution_stage = _validated_execution_stage(execution_stage)
14901525 active_node_name_set = (
14911526 frozenset(str(name) for name in active_node_names)
@@ -1508,10 +1543,10 @@ def build_path_c_descriptor_prim_func(
15081543 1,
15091544 (
15101545 int(validated_max_rows_per_launch)
1511- + DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH
1546+ + validated_rows_per_kernel_launch
15121547 - 1
15131548 )
1514- // DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH ,
1549+ // validated_rows_per_kernel_launch ,
15151550 )
15161551 if (
15171552 row_chunk_count is not None
@@ -1662,6 +1697,7 @@ def build_path_c_descriptor_prim_func(
16621697 loop_policy=validated_loop_policy,
16631698 max_rows_per_launch=validated_max_rows_per_launch,
16641699 row_dispatch_mode=validated_row_dispatch_mode,
1700+ rows_per_kernel_launch=validated_rows_per_kernel_launch,
16651701 execution_stage=validated_execution_stage,
16661702 active_node_names=active_node_name_set,
16671703 external_buffers=external_buffers_for_abi,
@@ -1780,7 +1816,7 @@ def build_path_c_descriptor_prim_func(
17801816 DESCRIPTOR_ROW_SUBCHUNK_INDEX_PARAM,
17811817 ).with_attr(
17821818 "tl.fusion.rows_per_kernel_launch",
1783- DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH ,
1819+ validated_rows_per_kernel_launch ,
17841820 ).with_attr(
17851821 "tl.fusion.row_subchunk_count",
17861822 row_subchunk_count,
@@ -1834,6 +1870,9 @@ def build_path_c_descriptor_prim_func(
18341870 prim_func._cppmega_path_c_physical_abi_policy = validated_physical_abi_policy
18351871 prim_func._cppmega_path_c_max_rows_per_launch = validated_max_rows_per_launch
18361872 prim_func._cppmega_path_c_row_dispatch_mode = validated_row_dispatch_mode
1873+ prim_func._cppmega_path_c_rows_per_kernel_launch = (
1874+ validated_rows_per_kernel_launch
1875+ )
18371876 prim_func._cppmega_path_c_execution_stage = validated_execution_stage
18381877 prim_func._cppmega_path_c_active_node_names = tuple(
18391878 sorted(active_node_name_set or ())
@@ -2180,6 +2219,7 @@ def _descriptor_prim_func_source(
21802219 loop_policy: str,
21812220 max_rows_per_launch: int | None,
21822221 row_dispatch_mode: str,
2222+ rows_per_kernel_launch: int,
21832223 execution_stage: str,
21842224 active_node_names: frozenset[str] | None,
21852225 external_buffers: Sequence[str],
@@ -2360,6 +2400,7 @@ def _descriptor_prim_func_source(
23602400 ),
23612401 max_rows_per_launch=max_rows_per_launch,
23622402 row_dispatch_mode=row_dispatch_mode,
2403+ rows_per_kernel_launch=rows_per_kernel_launch,
23632404 execution_stage=execution_stage,
23642405 active_node_names=active_node_names,
23652406 indent=indent,
@@ -4409,6 +4450,7 @@ def _append_row_phased_hidden_body(
44094450 train_step_loss_parameter_grad_buffers: Sequence[str],
44104451 max_rows_per_launch: int | None,
44114452 row_dispatch_mode: str,
4453+ rows_per_kernel_launch: int,
44124454 execution_stage: str,
44134455 active_node_names: frozenset[str] | None,
44144456 indent: str,
@@ -4450,8 +4492,8 @@ def _append_row_phased_hidden_body(
44504492 )
44514493 subchunk_count = max(
44524494 1,
4453- (int(max_rows_per_launch) + DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH - 1)
4454- // DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH ,
4495+ (int(max_rows_per_launch) + int(rows_per_kernel_launch) - 1)
4496+ // int(rows_per_kernel_launch) ,
44554497 )
44564498 row_chunk_assumptions = (
44574499 f"{indent * 2}T.assume({row_chunk_expr} >= 0)",
@@ -4671,13 +4713,13 @@ def append_forward_phase(lines: Sequence[str]) -> None:
46714713 f"{indent * 2}subchunk_row_chunk_start = "
46724714 f"T.min(logical_row_chunk_start + "
46734715 f"{DESCRIPTOR_ROW_SUBCHUNK_INDEX_PARAM} * "
4674- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4716+ f"{rows_per_kernel_launch }, "
46754717 "logical_row_chunk_stop)"
46764718 )
46774719 body.append(
46784720 f"{indent * 2}subchunk_row_chunk_stop = "
46794721 f"T.min(subchunk_row_chunk_start + "
4680- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4722+ f"{rows_per_kernel_launch }, "
46814723 "logical_row_chunk_stop)"
46824724 )
46834725 body.append(f"{indent * 2}row_chunk_start = subchunk_row_chunk_start")
@@ -4729,13 +4771,13 @@ def append_forward_phase(lines: Sequence[str]) -> None:
47294771 f"{indent * 2}subchunk_row_chunk_start = "
47304772 f"T.min(logical_row_chunk_start + "
47314773 f"{DESCRIPTOR_ROW_SUBCHUNK_INDEX_PARAM} * "
4732- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4774+ f"{rows_per_kernel_launch }, "
47334775 "logical_row_chunk_stop)"
47344776 )
47354777 body.append(
47364778 f"{indent * 2}subchunk_row_chunk_stop = "
47374779 f"T.min(subchunk_row_chunk_start + "
4738- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4780+ f"{rows_per_kernel_launch }, "
47394781 "logical_row_chunk_stop)"
47404782 )
47414783 body.append(f"{indent * 2}row_chunk_start = subchunk_row_chunk_start")
@@ -4864,13 +4906,13 @@ def append_forward_phase(lines: Sequence[str]) -> None:
48644906 f"{indent * 2}subchunk_row_chunk_start = "
48654907 f"T.min(logical_row_chunk_start + "
48664908 f"{DESCRIPTOR_ROW_SUBCHUNK_INDEX_PARAM} * "
4867- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4909+ f"{rows_per_kernel_launch }, "
48684910 "logical_row_chunk_stop)"
48694911 )
48704912 body.append(
48714913 f"{indent * 2}subchunk_row_chunk_stop = "
48724914 f"T.min(subchunk_row_chunk_start + "
4873- f"{DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH }, "
4915+ f"{rows_per_kernel_launch }, "
48744916 "logical_row_chunk_stop)"
48754917 )
48764918 body.append(f"{indent * 2}row_chunk_start = subchunk_row_chunk_start")
@@ -9087,7 +9129,11 @@ def _append_row_phased_m2rnn_bwd_body(
90879129 body.append(f"{indent * 3}{scalar0} = T.alloc_local((1,), \"float32\")")
90889130 body.append(f"{indent * 3}{scalar1} = T.alloc_local((1,), \"float32\")")
90899131 body.append(f"{indent * 3}{scalar2} = T.alloc_local((1,), \"float32\")")
9090- first_row_condition = "path_c_first_row_launch != 0" if launcher_chunked_rows else "row == 0"
9132+ first_row_condition = (
9133+ "path_c_first_row_launch != 0 and row == row_chunk_start"
9134+ if launcher_chunked_rows
9135+ else "row == 0"
9136+ )
90919137 time_rev_range = "row, row + 1" if launcher_chunked_rows else f"0, {sequence_length}"
90929138 body.append(f"{indent * 3}if {first_row_condition}:")
90939139 body.append(f"{indent * 4}if lane == 0:")
@@ -10402,7 +10448,9 @@ def _mamba3_emit_recompute_row(
1040210448 ):
1040310449 body.append(f"{indent * 3}{scalar} = T.alloc_local((1,), \"float32\")")
1040410450 first_row_condition = (
10405- "path_c_first_row_launch != 0" if launcher_chunked_rows else "row == 0"
10451+ "path_c_first_row_launch != 0 and row == row_chunk_start"
10452+ if launcher_chunked_rows
10453+ else "row == 0"
1040610454 )
1040710455 time_rev_range = "row, row + 1" if launcher_chunked_rows else f"0, {sequence_length}"
1040810456 body.append(f"{indent * 3}if {first_row_condition}:")
@@ -11237,6 +11285,17 @@ def _validated_max_rows_per_launch(max_rows_per_launch: int | None) -> int | Non
1123711285 return rows
1123811286
1123911287
11288+ def _validated_rows_per_kernel_launch(rows_per_kernel_launch: int | None) -> int:
11289+ rows = (
11290+ DESCRIPTOR_ROWS_PER_KERNEL_LAUNCH
11291+ if rows_per_kernel_launch is None
11292+ else int(rows_per_kernel_launch)
11293+ )
11294+ if rows <= 0:
11295+ raise ValueError("rows_per_kernel_launch must be positive")
11296+ return rows
11297+
11298+
1124011299def _validated_row_dispatch_mode(row_dispatch_mode: str) -> str:
1124111300 mode = str(row_dispatch_mode)
1124211301 if mode not in {
0 commit comments