(self)
| 1813 | |
| 1814 | @unittest.skipIf(not has_tf, "requires TensorFlow") |
| 1815 | def test_buffer_protocol_tf(self): |
| 1816 | dtypes_list = [ |
| 1817 | ( |
| 1818 | mx.bool_, |
| 1819 | tf.bool, |
| 1820 | np.bool_, |
| 1821 | ), |
| 1822 | ( |
| 1823 | mx.uint8, |
| 1824 | tf.uint8, |
| 1825 | np.uint8, |
| 1826 | ), |
| 1827 | ( |
| 1828 | mx.uint16, |
| 1829 | tf.uint16, |
| 1830 | np.uint16, |
| 1831 | ), |
| 1832 | ( |
| 1833 | mx.uint32, |
| 1834 | tf.uint32, |
| 1835 | np.uint32, |
| 1836 | ), |
| 1837 | (mx.uint64, tf.uint64, np.uint64), |
| 1838 | (mx.int8, tf.int8, np.int8), |
| 1839 | (mx.int16, tf.int16, np.int16), |
| 1840 | (mx.int32, tf.int32, np.int32), |
| 1841 | (mx.int64, tf.int64, np.int64), |
| 1842 | (mx.float16, tf.float16, np.float16), |
| 1843 | (mx.float32, tf.float32, np.float32), |
| 1844 | ( |
| 1845 | mx.complex64, |
| 1846 | tf.complex64, |
| 1847 | np.complex64, |
| 1848 | ), |
| 1849 | ] |
| 1850 | |
| 1851 | for mlx_dtype, tf_dtype, np_dtype in dtypes_list: |
| 1852 | a_np = np.random.uniform(low=0, high=100, size=(3, 4)).astype(np_dtype) |
| 1853 | a_tf = tf.constant(a_np, dtype=tf_dtype) |
| 1854 | a_mx = mx.array(np.array(a_tf)) |
| 1855 | for f in [ |
| 1856 | lambda x: x, |
| 1857 | lambda x: tf.transpose(x) if isinstance(x, tf.Tensor) else x.T, |
| 1858 | ]: |
| 1859 | mv_mx = memoryview(f(a_mx)) |
| 1860 | mv_tf = memoryview(f(a_tf)) |
| 1861 | if (mv_mx.c_contiguous and mv_tf.c_contiguous) or ( |
| 1862 | mv_mx.f_contiguous and mv_tf.f_contiguous |
| 1863 | ): |
| 1864 | self.assertEqual( |
| 1865 | mv_mx.strides, mv_tf.strides, f"{mlx_dtype}{tf_dtype}" |
| 1866 | ) |
| 1867 | self.assertEqual(mv_mx.shape, mv_tf.shape, f"{mlx_dtype}{tf_dtype}") |
| 1868 | self.assertFalse(mv_mx.readonly) |
| 1869 | back_to_npy = np.array(mv_mx) |
| 1870 | self.assertEqualArray( |
| 1871 | back_to_npy, |
| 1872 | f(a_tf), |
nothing calls this directly
no test coverage detected