Test a case where every other process produces a slice. We build the array directly with `global_to_host_array`.
(self, divisor: int)
| 2089 | self, |
| 2090 | logical_mesh: Union[MeshShape, HybridMeshShape], |
| 2091 | expected: Optional[Union[MeshShape, Exception]] = None, |
| 2092 | is_custom: bool = False, |
| 2093 | ): |
| 2094 | slice_physical_mesh = (16, 16, 1) |
| 2095 | num_slices = 2 |
| 2096 | coords = [ |
| 2097 | (x, y, z) |
| 2098 | for x in range(slice_physical_mesh[0]) |
| 2099 | for y in range(slice_physical_mesh[1]) |
| 2100 | for z in range(slice_physical_mesh[2]) |
| 2101 | ] |
| 2102 | devices = [ |
| 2103 | DummyMultiSliceTpuDevice( |
| 2104 | platform="tpu", |
| 2105 | device_kind="TPU v5 lite", |
| 2106 | process_index=(len(coords) * slice_index + ix) // 4, |
| 2107 | coords=coord, |
| 2108 | slice_index=slice_index, |
| 2109 | ) |
| 2110 | for ix, coord in enumerate(coords) |
| 2111 | for slice_index in range(num_slices) |
| 2112 | ] |
| 2113 | if isinstance(expected, Exception): |
| 2114 | with self.assertRaisesRegex(type(expected), str(expected)): |
| 2115 | create_device_mesh(mesh_shape=logical_mesh, devices=devices) |
| 2116 | else: |
| 2117 | # pylint: disable-next=protected-access |
| 2118 | custom_mesh_fn = mock.Mock(wraps=utils._reshape_mesh_to_rings) |
| 2119 | with mock.patch.object(utils, "_reshape_mesh_to_rings", custom_mesh_fn): |
| 2120 | device_mesh = create_device_mesh(mesh_shape=logical_mesh, devices=devices) |
| 2121 | if is_custom: |
| 2122 | self.assertEqual(custom_mesh_fn.call_count, num_slices) |
| 2123 | else: |
| 2124 | custom_mesh_fn.assert_not_called() |
| 2125 | # Check that the constructed mesh has the expected shape. |
| 2126 | self.assertEqual(expected or logical_mesh, device_mesh.shape) |
| 2127 | |
| 2128 | # Check that the sub_mesh along the first non-singleton mesh axis only contains devices |
| 2129 | # from one of the slices. |
| 2130 | mesh_shape = device_mesh.shape |
| 2131 | for dim in mesh_shape: |
| 2132 | if dim != 1: |
| 2133 | break |
| 2134 | device_mesh = device_mesh[0] |
| 2135 | for ix, sub_mesh in enumerate(device_mesh): |
| 2136 | self.assertTrue(all(el.slice_index == ix for el in sub_mesh.flatten())) |
| 2137 | |
| 2138 | @parameterized.parameters( |
| 2139 | {"logical_mesh": (8, 2, 4)}, |
| 2140 | {"logical_mesh": (16, 4)}, |
nothing calls this directly
no test coverage detected