(self)
| 830 | |
| 831 | @unittest.skipIf(not mx.is_available(mx.gpu), "No GPU available") |
| 832 | def test_custom_kernel_strides(self): |
| 833 | if mx.metal.is_available(): |
| 834 | source = """ |
| 835 | uint elem = thread_position_in_grid.x; |
| 836 | uint loc = elem_to_loc(elem, inp_shape, inp_strides, inp_ndim); |
| 837 | T tmp = inp[loc]; |
| 838 | out[elem] = metal::precise::exp(tmp) * threads_per_simdgroup; |
| 839 | """ |
| 840 | source_contig = """ |
| 841 | uint elem = thread_position_in_grid.x; |
| 842 | T tmp = inp[elem]; |
| 843 | out[elem] = metal::precise::exp(tmp) * threads_per_simdgroup; |
| 844 | """ |
| 845 | custom_kernel = mx.fast.metal_kernel |
| 846 | elif mx.cuda.is_available(): |
| 847 | source = """ |
| 848 | auto elem = cooperative_groups::this_grid().thread_rank(); |
| 849 | auto loc = elem_to_loc(elem, inp_shape.data(), inp_strides.data(), inp_ndim); |
| 850 | T tmp = inp[loc]; |
| 851 | out[elem] = exp(tmp) * WARP_SIZE; |
| 852 | """ |
| 853 | source_contig = """ |
| 854 | auto elem = cooperative_groups::this_grid().thread_rank(); |
| 855 | T tmp = inp[elem]; |
| 856 | out[elem] = exp(tmp) * WARP_SIZE; |
| 857 | """ |
| 858 | custom_kernel = mx.fast.cuda_kernel |
| 859 | |
| 860 | mx.random.seed(7) |
| 861 | a = mx.random.normal(shape=(3, 6)) |
| 862 | |
| 863 | # non contiguous |
| 864 | a = mx.tile(a[::2], [4, 1]) |
| 865 | |
| 866 | for contig in [True, False]: |
| 867 | kernel = custom_kernel( |
| 868 | name="myexp" + str(contig), |
| 869 | input_names=["inp"], |
| 870 | output_names=["out"], |
| 871 | source=source_contig if contig else source, |
| 872 | ensure_row_contiguous=contig, |
| 873 | ) |
| 874 | outputs = kernel( |
| 875 | inputs=[a], |
| 876 | template=[("T", mx.float32)], |
| 877 | grid=(a.size, 1, 1), |
| 878 | threadgroup=(256, 1, 1), |
| 879 | output_shapes=[a.shape], |
| 880 | output_dtypes=[a.dtype], |
| 881 | stream=mx.gpu, |
| 882 | ) |
| 883 | self.assertTrue(mx.allclose(mx.exp(a) * 32, outputs[0])) |
| 884 | |
| 885 | @unittest.skipIf(not mx.is_available(mx.gpu), "No GPU available") |
| 886 | def test_custom_kernel_helper(self): |
nothing calls this directly
no test coverage detected