compile_generic_fused_step
CompiledExecutable * compile_generic_fused_step(const TraceGraph & graph, const int & external_feeds, TensorId loss_id, const int & param_ids, const int & ghost_grad_ids, const int & output_target_ids, int * error_msg)Like compile_fused_training_step but the optimizer update math is captured in the same TraceGraph as the forward pass — no per-optimizer C++ emit branch. Each ghost_grad_id is a tensor placeholder that the Python wrapper reserved as the "grad input" of the optimizer update; this function binds those placeholders to MPSGraph-derived gradient tensors after the forward has been emitted, then continues emitting the remaining (optimizer) ops which now resolve their grad reads correctly.
Why this exists
The hardcoded path supports SGD / Adam / AdamW. Adding RMSprop /
Adagrad / Adadelta / Adamax / NAdam (and any future optimizer) via
the hardcoded path would duplicate the math already expressed by
each compile_optimizer subclass. This function lets the
Python wrapper reuse that math directly — trace it once into the
same graph, then bind the ghost grads here.
Output layout (in order):
- loss
- one entry per
output_target_ids[i](the trace ids of the new_param / new_state tensors the optimizer wrote into).
At run time, callers use run_executable_inplace with
output_targets = [loss_scratch, param_0, param_1, ...,
state_buf_0_0, state_buf_0_1, ...].