Format change using Black

This commit is contained in:
tankya2
2023-02-13 14:33:58 +08:00
parent 9890d1ffed
commit 98fa7650c1
2 changed files with 83 additions and 59 deletions

View File

@@ -1,12 +1,11 @@
import cupy as cp import cupy as cp
import numpy as np import numpy as np
EINSUM_SYMBOLS_BASE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" EINSUM_SYMBOLS_BASE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
class QiboCircuitToEinsum:
def __init__(self, circuit, dtype='complex128'):
class QiboCircuitToEinsum:
def __init__(self, circuit, dtype="complex128"):
self.backend = cp self.backend = cp
self.dtype = getattr(self.backend, dtype) self.dtype = getattr(self.backend, dtype)
@@ -15,31 +14,49 @@ class QiboCircuitToEinsum:
for gate in circuit.queue: for gate in circuit.queue:
targets = list(gate.target_qubits) targets = list(gate.target_qubits)
for target in targets: for target in targets:
self.input_tensor_counter[target] = self.input_tensor_counter[target] + 1 self.input_tensor_counter[target] = (
self.input_tensor_counter[target] + 1
)
controls = list(gate.control_qubits) controls = list(gate.control_qubits)
for control in controls: for control in controls:
self.input_tensor_counter[control] = self.input_tensor_counter[control] + 1 self.input_tensor_counter[control] = (
self.input_tensor_counter[control] + 1
)
gate_qubits = controls + targets gate_qubits = controls + targets
self.gates.append((cp.asarray(gate.matrix).reshape((2,) * 2 * len(gate_qubits)), gate_qubits)) self.gates.append(
(
cp.asarray(gate.matrix).reshape((2,) * 2 * len(gate_qubits)),
gate_qubits,
)
)
self.qubit_name = [indx for indx, value in enumerate(self.input_tensor_counter) if value > 0] self.qubit_name = [
indx for indx, value in enumerate(self.input_tensor_counter) if value > 0
]
def state_vector(self): def state_vector(self):
input_tensor_count = np.count_nonzero(self.input_tensor_counter) input_tensor_count = np.count_nonzero(self.input_tensor_counter)
input_operands = self._get_bitstring_tensors('0'*input_tensor_count, self.dtype, backend=self.backend) input_operands = self._get_bitstring_tensors(
"0" * input_tensor_count, self.dtype, backend=self.backend
)
mode_labels, qubits_frontier, next_frontier = self._init_mode_labels_from_qubits(self.qubit_name) (
mode_labels,
gate_mode_labels, gate_operands = self._parse_gates_to_mode_labels_operands(self.gates,
qubits_frontier, qubits_frontier,
next_frontier) next_frontier,
) = self._init_mode_labels_from_qubits(self.qubit_name)
gate_mode_labels, gate_operands = self._parse_gates_to_mode_labels_operands(
self.gates, qubits_frontier, next_frontier
)
operands = input_operands + gate_operands operands = input_operands + gate_operands
mode_labels += gate_mode_labels mode_labels += gate_mode_labels
expression = self._convert_mode_labels_to_expression(mode_labels, qubits_frontier) expression = self._convert_mode_labels_to_expression(
mode_labels, qubits_frontier
)
return expression, operands return expression, operands
@@ -54,7 +71,6 @@ class QiboCircuitToEinsum:
return chr(i + 140) return chr(i + 140)
def _init_mode_labels_from_qubits(self, qubits): def _init_mode_labels_from_qubits(self, qubits):
frontier_dict = {} frontier_dict = {}
n = len(qubits) n = len(qubits)
for x in range(n): for x in range(n):
@@ -62,24 +78,18 @@ class QiboCircuitToEinsum:
return [[i] for i in range(n)], frontier_dict, n return [[i] for i in range(n)], frontier_dict, n
def _get_bitstring_tensors(self, bitstring, dtype=np.complex128, backend=cp): def _get_bitstring_tensors(self, bitstring, dtype=np.complex128, backend=cp):
asarray = backend.asarray # _get_backend_asarray_func(backend) asarray = backend.asarray # _get_backend_asarray_func(backend)
state_0 = asarray([1, 0], dtype=dtype) state_0 = asarray([1, 0], dtype=dtype)
state_1 = asarray([0, 1], dtype=dtype) state_1 = asarray([0, 1], dtype=dtype)
basis_map = {'0': state_0, basis_map = {"0": state_0, "1": state_1}
'1': state_1}
operands = [basis_map[ibit] for ibit in bitstring] operands = [basis_map[ibit] for ibit in bitstring]
return operands return operands
def _parse_gates_to_mode_labels_operands( def _parse_gates_to_mode_labels_operands(
self, self, gates, qubits_frontier, next_frontier
gates,
qubits_frontier,
next_frontier
): ):
mode_labels = [] mode_labels = []
operands = [] operands = []
@@ -96,12 +106,15 @@ class QiboCircuitToEinsum:
return mode_labels, operands return mode_labels, operands
def _convert_mode_labels_to_expression(self, input_mode_labels, output_mode_labels): def _convert_mode_labels_to_expression(self, input_mode_labels, output_mode_labels):
out_list = [] out_list = []
for key in output_mode_labels: for key in output_mode_labels:
out_list.append(output_mode_labels[key]) out_list.append(output_mode_labels[key])
input_symbols = [''.join(map(self._get_symbol, idx)) for idx in input_mode_labels] input_symbols = [
expression = ','.join(input_symbols) + '->' + ''.join(map(self._get_symbol, out_list)) "".join(map(self._get_symbol, idx)) for idx in input_mode_labels
]
expression = (
",".join(input_symbols) + "->" + "".join(map(self._get_symbol, out_list))
)
return expression return expression

View File

@@ -5,24 +5,34 @@ import cupy as cp
from qibo.models import * from qibo.models import *
from timeit import default_timer as timer from timeit import default_timer as timer
def parser():
def parser():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--nqubits", default=10, type=int, help="Number of quibits in the circuits.") parser.add_argument(
"--nqubits", default=10, type=int, help="Number of quibits in the circuits."
)
parser.add_argument("--circuit", default="qft", type=str, parser.add_argument(
"--circuit",
default="qft",
type=str,
help="Type of circuit to use. See README for the list of " help="Type of circuit to use. See README for the list of "
"available circuits.") "available circuits.",
)
parser.add_argument("--precision", default='complex128', type=str, parser.add_argument(
"--precision",
default="complex128",
type=str,
help="Numerical precision of the simulation. " help="Numerical precision of the simulation. "
"Choose between 'complex128' and 'complex64'.") "Choose between 'complex128' and 'complex64'.",
)
return parser.parse_args() return parser.parse_args()
def run_bench(task, label):
def run_bench(task, label):
start = timer() start = timer()
result = task() result = task()
end = timer() end = timer()
@@ -31,8 +41,8 @@ def run_bench(task, label):
return result return result
def main(args: argparse.Namespace):
def main(args: argparse.Namespace):
print("Testing for %d nqubits" % (args.nqubits)) print("Testing for %d nqubits" % (args.nqubits))
nqubits = args.nqubits nqubits = args.nqubits
circuit_name = args.circuit circuit_name = args.circuit
@@ -48,12 +58,13 @@ def main(args: argparse.Namespace):
expression, operands = myconvertor.state_vector() expression, operands = myconvertor.state_vector()
result_qibo = run_bench(circuit, "Qibo") result_qibo = run_bench(circuit, "Qibo")
sv_cutn = run_bench(lambda:contract(expression, *operands), "cuQuantum cuTensorNet") sv_cutn = run_bench(
lambda: contract(expression, *operands), "cuQuantum cuTensorNet"
)
# print(f"is sv in agreement?", cp.allclose(sv_cutn.flatten(), result_qibo.state(numpy=True))) # print(f"is sv in agreement?", cp.allclose(sv_cutn.flatten(), result_qibo.state(numpy=True)))
assert cp.allclose(sv_cutn.flatten(), result_qibo.state(numpy=True)) assert cp.allclose(sv_cutn.flatten(), result_qibo.state(numpy=True))
if __name__ == "__main__": if __name__ == "__main__":
main(parser()) main(parser())