114114DESCRIPTOR_PORTABLE_KERNEL_BUFFER_LIMIT = 31
115115DESCRIPTOR_SHARED_SCRATCH_SPILL_THRESHOLD_BYTES = 4 * 1024
116116DESCRIPTOR_SHARED_SCRATCH_BUDGET_BYTES = 24 * 1024
117+ MAMBA3_BWD_REPLAY_CHECKPOINT_INTERVAL = 64
117118_DESCRIPTOR_ROOT_READS_MARKER = "cppmega_path_c_root_reads"
118119_DESCRIPTOR_ROOT_WRITES_MARKER = "cppmega_path_c_root_writes"
119120_EXACT_ROW_PHASED_BACKWARD_OPS = frozenset (
@@ -1420,7 +1421,11 @@ def build_path_c_descriptor_prim_func(
14201421 )
14211422 if validated_loop_policy == DESCRIPTOR_LOOP_POLICY_ROW_PHASED_HIDDEN :
14221423 prim_func = prim_func .with_attr ("tl.fusion.disable_tir_simplify" , True )
1423- owner_output_param_indices = tuple (range (len (physical_abi_plan .param_lines )))
1424+ owner_output_param_indices = tuple (
1425+ idx
1426+ for idx , param in enumerate (prim_func .params )
1427+ if param in prim_func .buffer_map
1428+ )
14241429 if owner_output_param_indices :
14251430 prim_func = prim_func .with_attr (
14261431 "tilelang_out_idx" ,
@@ -3028,10 +3033,7 @@ def _spill_large_shared_scratch_to_abi(
30283033 byte_count = _flattened_extent (shape ) * _DTYPE_NBYTES [dtype ]
30293034 total_shared_bytes += byte_count
30303035 scratch_name = match .group ("name" )
3031- force_scratch_abi = (
3032- scratch_name in DESCRIPTOR_ROW_PHASED_BWD_SCRATCH_ABI_BUFFERS
3033- or scratch_name .endswith ("_mamba3_h_steps" )
3034- )
3036+ force_scratch_abi = scratch_name in DESCRIPTOR_ROW_PHASED_BWD_SCRATCH_ABI_BUFFERS
30353037 if (
30363038 byte_count > DESCRIPTOR_SHARED_SCRATCH_SPILL_THRESHOLD_BYTES
30373039 or force_scratch_abi
@@ -9139,7 +9141,8 @@ def _append_row_phased_mamba3_bwd_body(
91399141 out_inner = _scratch_name (node , "mamba3_out_inner" )
91409142 y_skip = _scratch_name (node , "mamba3_y_skip" )
91419143 out_inner_grad = _scratch_name (node , "mamba3_out_inner_grad" )
9142- h_steps = _scratch_name (node , "mamba3_h_steps" )
9144+ h_checkpoint = _scratch_name (node , "mamba3_h_checkpoint" )
9145+ angle_checkpoint = _scratch_name (node , "mamba3_angle_checkpoint" )
91439146 h_prev = _scratch_name (node , "mamba3_h_prev" )
91449147 h_next = _scratch_name (node , "mamba3_h_next" )
91459148 dh = _scratch_name (node , "mamba3_dh" )
@@ -9177,6 +9180,9 @@ def _append_row_phased_mamba3_bwd_body(
91779180 time_rev = _scratch_name (node , "time_rev" )
91789181 time_idx = _scratch_name (node , "time_idx" )
91799182 replay_time = _scratch_name (node , "replay_time" )
9183+ replay_offset = _scratch_name (node , "replay_offset" )
9184+ checkpoint_idx = _scratch_name (node , "checkpoint_idx" )
9185+ checkpoint_start = _scratch_name (node , "checkpoint_start" )
91809186 src_row = _scratch_name (node , "src_row" )
91819187 src_hist = _scratch_name (node , "src_hist" )
91829188 hidden_loop = _scratch_name (node , "hidden_loop" )
@@ -9209,6 +9215,9 @@ def _append_row_phased_mamba3_bwd_body(
92099215 conv_b_offset = inner_dim
92109216 conv_c_offset = inner_dim + bc_dim
92119217 rot_dim = min (state_dim , 2 * rope_angles )
9218+ checkpoint_interval = MAMBA3_BWD_REPLAY_CHECKPOINT_INTERVAL
9219+ checkpoint_count = (sequence_length + checkpoint_interval - 1 ) // checkpoint_interval
9220+ angle_extent = heads * rope_angles
92129221
92139222 def _mamba3_hidden_expr (time_expr : str , hidden_expr : str ) -> str :
92149223 return _node_indexed_canonical_or_positional_input_expr (
@@ -9246,7 +9255,6 @@ def _mamba3_emit_recompute_row(
92469255 level : int ,
92479256 update_angle : bool ,
92489257 update_state : bool ,
9249- compute_h_prev : bool ,
92509258 ) -> None :
92519259 body .append (f"{ indent * level } for { proj_dim } in T.serial(0, { in_proj_dim } ):" )
92529260 body .append (f"{ indent * (level + 1 )} { sum_scratch } [0] = 0.0" )
@@ -9555,11 +9563,6 @@ def _mamba3_emit_recompute_row(
95559563 f"{ indent * (level + 2 )} { state_idx } = "
95569564 f"{ head } * { head_dim * state_dim } + { hidden_dim } * { state_dim } + { state_loop } "
95579565 )
9558- if compute_h_prev :
9559- body .append (
9560- f"{ indent * (level + 2 )} { h_prev } [{ state_idx } ] = "
9561- f"{ h_steps } [{ time_expr } * { state_extent } + { state_idx } ]"
9562- )
95639566 if update_state :
95649567 body .append (
95659568 f"{ indent * (level + 2 )} { h_next } [{ state_idx } ] = "
@@ -9591,7 +9594,7 @@ def _mamba3_emit_recompute_row(
95919594 f"{ y_skip } [{ feature } ] * { projected } [{ z_offset } + { feature } ] * { scalar0 } [0]"
95929595 )
95939596
9594- body .append (f"{ indent * 3 } # mamba3_mimo_bwd_policy: exact_reverse_recompute " )
9597+ body .append (f"{ indent * 3 } # mamba3_mimo_bwd_policy: exact_reverse_checkpoint_replay " )
95959598 for name , extent in (
95969599 (projected , in_proj_dim ),
95979600 (project_grad , in_proj_dim ),
@@ -9601,7 +9604,8 @@ def _mamba3_emit_recompute_row(
96019604 (out_inner , inner_dim ),
96029605 (y_skip , inner_dim ),
96039606 (out_inner_grad , inner_dim ),
9604- (h_steps , (sequence_length + 1 ) * state_extent ),
9607+ (h_checkpoint , (checkpoint_count + 1 ) * state_extent ),
9608+ (angle_checkpoint , (checkpoint_count + 1 ) * angle_extent ),
96059609 (h_prev , state_extent ),
96069610 (h_next , state_extent ),
96079611 (dh , state_extent ),
@@ -9630,7 +9634,11 @@ def _mamba3_emit_recompute_row(
96309634 (angle_cumsum , heads * rope_angles ),
96319635 (angle_grad , heads * rope_angles ),
96329636 ):
9633- alloc = "T.alloc_shared" if name == h_steps else "T.alloc_local"
9637+ alloc = (
9638+ "T.alloc_shared"
9639+ if name in {h_checkpoint , angle_checkpoint }
9640+ else "T.alloc_local"
9641+ )
96349642 body .append (f"{ indent * 3 } { name } = { alloc } (({ extent } ,), \" float32\" )" )
96359643 for scalar in (
96369644 stage_grad ,
@@ -9687,32 +9695,67 @@ def _mamba3_emit_recompute_row(
96879695 default = "0.0" ,
96889696 )
96899697 body .append (f"{ indent * 6 } { h_next } [{ state_idx } ] = { h0_expr } " )
9690- body .append (f"{ indent * 6 } { h_steps } [{ state_idx } ] = { h0_expr } " )
9698+ body .append (f"{ indent * 6 } { h_checkpoint } [{ state_idx } ] = { h0_expr } " )
96919699 body .append (f"{ indent * 6 } { dh } [{ state_idx } ] = 0.0" )
96929700 body .append (f"{ indent * 5 } for { grad_flat } in T.serial(0, { heads * rope_angles } ):" )
96939701 body .append (f"{ indent * 6 } { angle_cumsum } [{ grad_flat } ] = 0.0" )
9702+ body .append (f"{ indent * 6 } { angle_checkpoint } [{ grad_flat } ] = 0.0" )
96949703 body .append (f"{ indent * 6 } { angle_grad } [{ grad_flat } ] = 0.0" )
96959704 body .append (f"{ indent * 5 } for { replay_time } in T.serial(0, { sequence_length } ):" )
96969705 _mamba3_emit_recompute_row (
96979706 replay_time ,
96989707 level = 6 ,
96999708 update_angle = True ,
97009709 update_state = True ,
9701- compute_h_prev = False ,
97029710 )
9703- body .append (f"{ indent * 6 } for { state_idx } in T.serial(0, { state_extent } ):" )
9711+ body .append (f"{ indent * 6 } if (({ replay_time } + 1) % { checkpoint_interval } ) == 0:" )
9712+ body .append (
9713+ f"{ indent * 7 } { checkpoint_idx } = ({ replay_time } + 1) // { checkpoint_interval } "
9714+ )
9715+ body .append (f"{ indent * 7 } for { state_idx } in T.serial(0, { state_extent } ):" )
97049716 body .append (
9705- f"{ indent * 7 } { h_steps } [( { replay_time } + 1) * { state_extent } + { state_idx } ] = "
9717+ f"{ indent * 8 } { h_checkpoint } [ { checkpoint_idx } * { state_extent } + { state_idx } ] = "
97069718 f"{ h_next } [{ state_idx } ]"
97079719 )
9720+ body .append (f"{ indent * 7 } for { grad_flat } in T.serial(0, { angle_extent } ):" )
9721+ body .append (
9722+ f"{ indent * 8 } { angle_checkpoint } [{ checkpoint_idx } * { angle_extent } + { grad_flat } ] = "
9723+ f"{ angle_cumsum } [{ grad_flat } ]"
9724+ )
97089725 body .append (f"{ indent * 5 } for { time_rev } in T.serial(0, { sequence_length } ):" )
97099726 body .append (f"{ indent * 6 } { time_idx } = { sequence_length - 1 } - { time_rev } " )
9727+ body .append (f"{ indent * 6 } { checkpoint_idx } = { time_idx } // { checkpoint_interval } " )
9728+ body .append (
9729+ f"{ indent * 6 } { checkpoint_start } = { checkpoint_idx } * { checkpoint_interval } "
9730+ )
9731+ body .append (f"{ indent * 6 } for { state_idx } in T.serial(0, { state_extent } ):" )
9732+ body .append (
9733+ f"{ indent * 7 } { h_next } [{ state_idx } ] = "
9734+ f"{ h_checkpoint } [{ checkpoint_idx } * { state_extent } + { state_idx } ]"
9735+ )
9736+ body .append (f"{ indent * 6 } for { grad_flat } in T.serial(0, { angle_extent } ):" )
9737+ body .append (
9738+ f"{ indent * 7 } { angle_cumsum } [{ grad_flat } ] = "
9739+ f"{ angle_checkpoint } [{ checkpoint_idx } * { angle_extent } + { grad_flat } ]"
9740+ )
9741+ body .append (f"{ indent * 6 } for { replay_offset } in T.serial(0, { checkpoint_interval } ):" )
9742+ body .append (
9743+ f"{ indent * 7 } { replay_time } = { checkpoint_start } + { replay_offset } "
9744+ )
9745+ body .append (f"{ indent * 7 } if { replay_time } < { time_idx } :" )
9746+ _mamba3_emit_recompute_row (
9747+ replay_time ,
9748+ level = 8 ,
9749+ update_angle = True ,
9750+ update_state = True ,
9751+ )
9752+ body .append (f"{ indent * 6 } for { state_idx } in T.serial(0, { state_extent } ):" )
9753+ body .append (f"{ indent * 7 } { h_prev } [{ state_idx } ] = { h_next } [{ state_idx } ]" )
97109754 _mamba3_emit_recompute_row (
97119755 time_idx ,
97129756 level = 6 ,
9713- update_angle = False ,
9714- update_state = False ,
9715- compute_h_prev = True ,
9757+ update_angle = True ,
9758+ update_state = True ,
97169759 )
97179760 body .append (f"{ indent * 6 } for { proj_dim } in T.serial(0, { in_proj_dim } ):" )
97189761 body .append (f"{ indent * 7 } { project_grad } [{ proj_dim } ] = 0.0" )
0 commit comments