(self)
| 771 | |
| 772 | @unittest.skipIf(not mx.is_available(mx.gpu), "No GPU available") |
| 773 | def test_custom_kernel_args(self): |
| 774 | if mx.metal.is_available(): |
| 775 | source = """ |
| 776 | uint elem = thread_position_in_grid.x; |
| 777 | T tmp = a[0]; |
| 778 | if (e) { |
| 779 | out1[elem] = a[1] + b[2] + c[3] + d + f; |
| 780 | } else { |
| 781 | out1[elem] = 1; |
| 782 | } |
| 783 | out2[elem] = a[1] + b[2] + c[1] - d; |
| 784 | """ |
| 785 | custom_kernel = mx.fast.metal_kernel |
| 786 | elif mx.cuda.is_available(): |
| 787 | source = """ |
| 788 | auto elem = cooperative_groups::this_grid().thread_rank(); |
| 789 | T tmp = a[0]; |
| 790 | if (e) { |
| 791 | out1[elem] = a[1] + b[2] + static_cast<float>(c[3]) + d[0] + f; |
| 792 | } else { |
| 793 | out1[elem] = 1; |
| 794 | } |
| 795 | out2[elem] = a[1] + b[2] + static_cast<float>(c[1]) - d[0]; |
| 796 | """ |
| 797 | custom_kernel = mx.fast.cuda_kernel |
| 798 | |
| 799 | mx.random.seed(7) |
| 800 | a = mx.random.normal(shape=(3, 6)) |
| 801 | c = mx.random.normal(shape=(2, 2)).astype(mx.bfloat16) |
| 802 | |
| 803 | kernel = custom_kernel( |
| 804 | name="arg_test", |
| 805 | input_names=["a", "b", "c", "d"], |
| 806 | output_names=["out1", "out2"], |
| 807 | source=source, |
| 808 | ) |
| 809 | out = kernel( |
| 810 | inputs=[ |
| 811 | a, |
| 812 | mx.array([3, 4, 5]), |
| 813 | c, |
| 814 | 7.3, |
| 815 | ], |
| 816 | template=[ |
| 817 | ("e", True), |
| 818 | ("f", 3), |
| 819 | ("T", mx.float16), |
| 820 | ], |
| 821 | grid=(6, 1, 1), |
| 822 | threadgroup=(2, 1, 1), |
| 823 | output_shapes=[(3, 2), (3, 2)], |
| 824 | output_dtypes=[mx.float32, mx.int32], |
| 825 | stream=mx.gpu, |
| 826 | ) |
| 827 | |
| 828 | self.assertTrue(mx.allclose(out[0], mx.full((3, 2), 14.0484))) |
| 829 | self.assertTrue(mx.allclose(out[1], mx.full((3, 2), -2, dtype=mx.int32))) |
| 830 |
nothing calls this directly
no test coverage detected