braket.default_simulator.simulation_strategies.batch_operation_strategy module¶

braket.default_simulator.simulation_strategies.batch_operation_strategy.
apply_operations
(state: numpy.ndarray, qubit_count: int, operations: List[braket.default_simulator.operation.GateOperation], batch_size: int) → numpy.ndarray[source]¶ Applies operations to a state vector in batches of size \(batch\_size\).
\(operations\) is partitioned into contiguous batches of size \(batch\_size\) (with remainder). The state vector is treated as a type \((qubit\_count, 0)\) tensor, and each operation is treated as a type \((target\_length, target\_length)\) tensor (where \(target\_length\) is the number of targets the operation acts on), and each batch is contracted in an order optimized among the operations in the batch. Larger batches can be significantly faster (although this is not guaranteed), but will use more memory.
For example, if we have a 4qubit state \(S\) and a batch with two gates \(G1\) and \(G2\) that act on qubits 0 and 1 and 1 and 3, respectively, then the state vector after applying the batch is \(S^{mokp} = S^{ijkl} G1^{mn}_{ij} G2^{op}_{nl}\).
Depending on the batch size, number of qubits, and the number and types of gates, the speed can be more than twice that of applying operations one at a time. Empirically, noticeable performance improvements were observed starting with a batch size of 10, with increasing performance gains up to a batch size of 50. We tested this with 16 GB of memory. For batch sizes greater than 50, consider using an environment with more than 16 GB of memory.
Parameters:  state (np.ndarray) – The state vector to apply \(operations\) to, as a type \((qubit\_count, 0)\) tensor
 qubit_count (int) – The number of qubits in the state
 operations (List[GateOperation]) – The operations to apply to the state vector
 batch_size – The number of operations to contract in each batch
Returns: np.ndarray – The state vector after applying the given operations, as a type (num_qubits, 0) tensor