Handle addmm: self + (mat1 @ mat2). addmm(self, mat1, mat2, *, beta=1, alpha=1) computes: beta * self + alpha * (mat1 @ mat2) This is typically the result of decomposing linear(x, w, b) in Edge IR: permute(w) -> addmm(b, x, permuted_w) For the common case where beta=1
(P: MLXProgramBuilder, n: Node)
| 818 | |
| 819 | @REGISTRY.register(target=[torch.ops.aten.addmm.default]) |
| 820 | def _addmm_handler(P: MLXProgramBuilder, n: Node) -> Slot: |
| 821 | """Handle addmm: self + (mat1 @ mat2). |
| 822 | |
| 823 | addmm(self, mat1, mat2, *, beta=1, alpha=1) computes: |
| 824 | beta * self + alpha * (mat1 @ mat2) |
| 825 | |
| 826 | This is typically the result of decomposing linear(x, w, b) in Edge IR: |
| 827 | permute(w) -> addmm(b, x, permuted_w) |
| 828 | |
| 829 | For the common case where beta=1 and alpha=1, this is equivalent to: |
| 830 | mat1 @ mat2 + self |
| 831 | |
| 832 | We use AddmmNode which calls matmul directly (no transposition needed). |
| 833 | """ |
| 834 | args = P.args(n) |
| 835 | kwargs = P.kwargs(n) |
| 836 | require_args(args, 3, 3, "aten.addmm") |
| 837 | require_kwargs(kwargs, {"beta", "alpha"}, "aten.addmm") |
| 838 | bias, mat1, mat2 = args[0], args[1], args[2] |
| 839 | |
| 840 | beta = kwargs.get("beta", 1) |
| 841 | alpha = kwargs.get("alpha", 1) |
| 842 | |
| 843 | out = P.make_or_get_slot(n) |
| 844 | |
| 845 | # Emit AddmmNode with alpha and beta parameters |
| 846 | P.emit( |
| 847 | AddmmNode( |
| 848 | mat1=P.slot_to_tid(mat1), |
| 849 | mat2=P.slot_to_tid(mat2), |
| 850 | out=P.slot_to_tid(out), |
| 851 | bias=P.slot_to_tid(bias), |
| 852 | alpha=float(alpha), |
| 853 | beta=float(beta), |
| 854 | ) |
| 855 | ) |
| 856 | return out |
| 857 | |
| 858 | |
| 859 | @REGISTRY.register( |
nothing calls this directly
no test coverage detected