Computes a device_assignment of a computation across a TPU topology. Attempts to choose a compact grid of cores for locality. Returns a `DeviceAssignment` that describes the cores in the topology assigned to each core of each replica. `computation_shape` and `computation_stride` values sh
(topology,
computation_shape=None,
computation_stride=None,
num_replicas=1)
| 213 | |
| 214 | |
| 215 | def device_assignment(topology, |
| 216 | computation_shape=None, |
| 217 | computation_stride=None, |
| 218 | num_replicas=1): |
| 219 | """Computes a device_assignment of a computation across a TPU topology. |
| 220 | |
| 221 | Attempts to choose a compact grid of cores for locality. |
| 222 | |
| 223 | Returns a `DeviceAssignment` that describes the cores in the topology assigned |
| 224 | to each core of each replica. |
| 225 | |
| 226 | `computation_shape` and `computation_stride` values should be powers of 2 for |
| 227 | optimal packing. |
| 228 | |
| 229 | Args: |
| 230 | topology: A `Topology` object that describes the TPU cluster topology. |
| 231 | To obtain a TPU topology, evaluate the `Tensor` returned by |
| 232 | `initialize_system` using `Session.run`. Either a serialized |
| 233 | `TopologyProto` or a `Topology` object may be passed. Note: you must |
| 234 | evaluate the `Tensor` first; you cannot pass an unevaluated `Tensor` here. |
| 235 | computation_shape: A rank 1 int32 numpy array with size equal to the |
| 236 | topology rank, describing the shape of the computation's block of cores. |
| 237 | If None, the `computation_shape` is `[1] * topology_rank`. |
| 238 | computation_stride: A rank 1 int32 numpy array of size `topology_rank`, |
| 239 | describing the inter-core spacing of the `computation_shape` cores in the |
| 240 | TPU topology. If None, the `computation_stride` is `[1] * topology_rank`. |
| 241 | num_replicas: The number of computation replicas to run. The replicas will |
| 242 | be packed into the free spaces of the topology. |
| 243 | |
| 244 | Returns: |
| 245 | A DeviceAssignment object, which describes the mapping between the logical |
| 246 | cores in each computation replica and the physical cores in the TPU |
| 247 | topology. |
| 248 | |
| 249 | Raises: |
| 250 | ValueError: If `topology` is not a valid `Topology` object. |
| 251 | ValueError: If `computation_shape` or `computation_stride` are not 1D int32 |
| 252 | numpy arrays with shape [3] where all values are positive. |
| 253 | ValueError: If computation's replicas cannot fit into the TPU topology. |
| 254 | """ |
| 255 | # Deserialize the Topology proto, if it is a string. |
| 256 | if isinstance(topology, bytes): |
| 257 | topology = Topology(serialized=topology) |
| 258 | |
| 259 | if not isinstance(topology, Topology): |
| 260 | raise ValueError("`topology` is not a Topology object; got {}".format( |
| 261 | type(topology))) |
| 262 | |
| 263 | topology_rank = len(topology.mesh_shape) |
| 264 | mesh_shape = topology.mesh_shape |
| 265 | if computation_shape is None: |
| 266 | computation_shape = np.array([1] * topology_rank, dtype=np.int32) |
| 267 | else: |
| 268 | computation_shape = np.asarray(computation_shape, dtype=np.int32) |
| 269 | |
| 270 | if computation_stride is None: |
| 271 | computation_stride = np.array([1] * topology_rank, dtype=np.int32) |
| 272 | else: |
no test coverage detected