Handle aten.slice_scatter: return a copy of self with self[dim][start:end:step] = src.
(P: MLXProgramBuilder, n: Node)
| 1861 | |
| 1862 | @REGISTRY.register(target=[torch.ops.aten.slice_scatter.default]) |
| 1863 | def _slice_scatter_handler(P: MLXProgramBuilder, n: Node) -> Slot: |
| 1864 | """Handle aten.slice_scatter: return a copy of self with self[dim][start:end:step] = src.""" |
| 1865 | args = P.args(n) |
| 1866 | require_args(args, 2, 6, "aten.slice_scatter") |
| 1867 | require_kwargs(P.kwargs(n), set(), "aten.slice_scatter") |
| 1868 | self_tensor = args[0] |
| 1869 | src = args[1] |
| 1870 | dim = args[2] if len(args) > 2 else 0 |
| 1871 | start = args[3] if len(args) > 3 else 0 |
| 1872 | end = args[4] if len(args) > 4 else None |
| 1873 | step = args[5] if len(args) > 5 else 1 |
| 1874 | |
| 1875 | # If end is None, default to dim size |
| 1876 | if end is None: |
| 1877 | input_meta = n.args[0].meta.get("val") |
| 1878 | if input_meta is not None: |
| 1879 | end = input_meta.shape[dim] |
| 1880 | else: |
| 1881 | raise ValueError( |
| 1882 | "aten.slice_scatter: end=None requires input shape metadata" |
| 1883 | ) |
| 1884 | |
| 1885 | require_static_int(step, "step", "aten.slice_scatter") |
| 1886 | assert step >= 1, f"aten.slice_scatter: step must be >= 1, got {step}" |
| 1887 | |
| 1888 | out = P.make_or_get_slot(n) |
| 1889 | P.emit( |
| 1890 | SliceUpdateNode( |
| 1891 | dst=P.slot_to_tid(self_tensor), |
| 1892 | update=P.slot_to_tid(src), |
| 1893 | out=P.slot_to_tid(out), |
| 1894 | axis=P.to_int_or_vid(dim), |
| 1895 | start=P.to_int_or_vid(start), |
| 1896 | stop=P.to_int_or_vid(end), |
| 1897 | step=step, |
| 1898 | ) |
| 1899 | ) |
| 1900 | return out |
| 1901 | |
| 1902 | |
| 1903 | @REGISTRY.register(target=[torch.ops.aten.scatter_add.default]) |
nothing calls this directly
no test coverage detected