(P: MLXProgramBuilder, n: Node)
| 788 | |
| 789 | @REGISTRY.register(target=[torch.ops.aten.linear.default]) |
| 790 | def _linear_handler(P: MLXProgramBuilder, n: Node) -> Slot: |
| 791 | args = P.args(n) |
| 792 | require_args(args, 2, 3, "aten.linear") |
| 793 | require_kwargs(P.kwargs(n), set(), "aten.linear") |
| 794 | x, w = args[0], args[1] |
| 795 | b = args[2] if len(args) > 2 else None |
| 796 | out = P.make_or_get_slot(n) |
| 797 | |
| 798 | # Transpose weight: linear(x, w) = x @ w.T |
| 799 | _, w_t = P.make_tmp_slot() |
| 800 | P.emit( |
| 801 | TransposeNode( |
| 802 | x=P.slot_to_tid(w), |
| 803 | out=P.slot_to_tid(w_t), |
| 804 | perm=[1, 0], |
| 805 | ) |
| 806 | ) |
| 807 | |
| 808 | P.emit( |
| 809 | AddmmNode( |
| 810 | mat1=P.slot_to_tid(x), |
| 811 | mat2=P.slot_to_tid(w_t), |
| 812 | out=P.slot_to_tid(out), |
| 813 | bias=P.slot_to_tid(b) if b else None, |
| 814 | ) |
| 815 | ) |
| 816 | return out |
| 817 | |
| 818 | |
| 819 | @REGISTRY.register(target=[torch.ops.aten.addmm.default]) |
nothing calls this directly
no test coverage detected