@@ -61,14 +61,11 @@ class NonLinearOps {
6161};
6262
6363// ----------------------------------------------------------------------------
64- // Recomputable chain analyzer + cloner: decide whether a forward SSA value can
65- // be reconstructed in the reverse-pass scope from already-stack-backed allocas,
66- // kernel args, constants, and loop indices, and clone the DAG at a target
67- // insertion point. Cross-stage shared infrastructure: used by
68- // `EliminateRecomputableAdStackPushes` (forward_state_spill stage) to drop
69- // pushes whose values are recomputable, and by `BackupSSA::generic_visit`
70- // (post_adjoint_cleanup stage) to clone such chains in place of cross-block
71- // SSA reads.
64+ // Recomputable chain analyzer + cloner: decide whether a forward SSA value can be reconstructed in the reverse-pass
65+ // scope from already-stack-backed allocas, kernel args, constants, and loop indices, and clone the DAG at a target
66+ // insertion point. Cross-stage shared infrastructure: used by `EliminateRecomputableAdStackPushes`
67+ // (forward_state_spill stage) to drop pushes whose values are recomputable, and by `BackupSSA::generic_visit`
68+ // (post_adjoint_cleanup stage) to clone such chains in place of cross-block SSA reads.
7269// ----------------------------------------------------------------------------
7370
7471// Returns true iff `stmt`'s transitive operand DAG terminates at recomputable leaves via side-effect-free
@@ -107,9 +104,7 @@ class RecomputableChainAnalyzer {
107104 // Recomputable leaves: ConstStmt, ArgLoadStmt, AdStackLoadTopStmt, AdStackAllocaStmt. LoopIndexStmt is
108105 // intentionally excluded - cloning a LoopIndexStmt copies the reference to the forward RangeForStmt,
109106 // but the cloned consumer lives inside the reverse RangeForStmt (a separate stmt with its own loop
110- // index), so the cloned read points at undefined state and silently double-accumulates gradients
111- // (`test_adstack_sum_linear`). A future MakeAdjoint coordination pass that tracks
112- // forward-RangeFor-to-reverse-RangeFor mapping could lift this restriction.
107+ // index), so the cloned read points at undefined state and silently double-accumulates gradients.
113108 //
114109 // AdStackLoadTopStmt as a leaf is correct under the dominance + control-flow-consumer + self-load
115110 // guards in `EliminateRecomputableAdStackPushes::run_one_pass`. The reasoning:
@@ -146,11 +141,9 @@ class RecomputableChainAnalyzer {
146141 // before reverse runs, so the reverse re-read sees the kernel's final post-write state. If a global is
147142 // mutated by the forward and then re-read by the reverse clone, the values can differ.
148143 //
149- // Most rigid-step kernel chain leaves are reads of input parameters (mass, inertia, joint params,
150- // morphology) that the kernel does NOT write. For those, the re-read returns the same value.
151- // Conservative analysis: a future safety check could prove the SNode is read-only in the kernel; until
152- // then this path relies on the test suite's gradient-correctness asserts to surface any mutated-global
153- // miscompilation.
144+ // Chain leaves that pass this branch are typically reads of kernel-input parameters not written by the
145+ // kernel; for those, the re-read returns the same value as the forward read. The pass does not statically
146+ // verify SNode read-only-ness, and mutated-global cases would silently produce wrong gradients.
154147 bool is_interior = stmt->is <UnaryOpStmt>() || stmt->is <BinaryOpStmt>() || stmt->is <TernaryOpStmt>() ||
155148 stmt->is <MatrixPtrStmt>() || stmt->is <GlobalPtrStmt>() || stmt->is <ExternalPtrStmt>() ||
156149 stmt->is <GlobalLoadStmt>();
@@ -214,9 +207,8 @@ class RecomputableChainCloner {
214207};
215208
216209// ----------------------------------------------------------------------------
217- // ADTransform: shared base for reverse-mode (MakeAdjoint) and forward-mode
218- // (MakeDual) IR builders. All methods are inline so derived classes in
219- // separate translation units can use them without ODR concerns.
210+ // ADTransform: shared base for reverse-mode (MakeAdjoint) and forward-mode (MakeDual) IR builders. Methods are inline
211+ // so derived classes in separate translation units can use them without ODR concerns.
220212// ----------------------------------------------------------------------------
221213class ADTransform : public IRVisitor {
222214 protected:
0 commit comments