From af09251f126a68265ed2e2bdd9fe4dc422dfd503 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Wed, 9 Aug 2023 09:30:04 -0700 Subject: [PATCH 01/59] Adding a white space --- examples/toffoli_instantiation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toffoli_instantiation.py b/examples/toffoli_instantiation.py index b89157e..55057f3 100644 --- a/examples/toffoli_instantiation.py +++ b/examples/toffoli_instantiation.py @@ -21,7 +21,7 @@ def run_toffoli_instantiation(dist_tol_requested = 1e-10): dist_tol = dist_tol_requested, # Stopping criteria for distance max_iters = 100000, # Maximum number of iterations - min_iters = 10, # Minimum number of iterations + min_iters = 10, # Minimum number of iterations #One step plateau detection - #diff_tol_a + diff_tol_r ∗ |c(i)| <= |c(i)|-|c(i-1)| From f4c3fe2fda2de541562de747ac2c55d0bd758e03 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 14:36:25 -0700 Subject: [PATCH 02/59] Adding the single edge tensor - find better name.. --- bqskitgpu/singlelegedtensor.py | 152 ++++++++++++++++++++++++++++++++ tests/test_single_leg_tensor.py | 82 +++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 bqskitgpu/singlelegedtensor.py create mode 100644 tests/test_single_leg_tensor.py diff --git a/bqskitgpu/singlelegedtensor.py b/bqskitgpu/singlelegedtensor.py new file mode 100644 index 0000000..100da43 --- /dev/null +++ b/bqskitgpu/singlelegedtensor.py @@ -0,0 +1,152 @@ +from __future__ import annotations + +import jax.numpy as jnp + +from bqskit.qis.unitary import UnitaryMatrix + +from typing import Sequence + +from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax + + +class SingleLegSideTensor(): + """ + The class represents a tensor that has only a single leg in one of his sides. + The single leg will always be index 0 + """ + + def __init__(self, num_qudits: int, radixes: Sequence[int] = [], list_of_states:Sequence=[], tensor=None, single_leg_radix=None) -> None: + + if len(list_of_states) > 0: + first_state = list_of_states[0] + + assert any(d==1 for d in first_state.shape ) + assert all(s.shape==first_state.shape for s in list_of_states) + + self.num_qudits = num_qudits + self.num_of_legs = num_qudits + 1 + self.radixes = tuple(radixes if len(radixes) > 0 else [2] * num_qudits) + self.single_leg_radix = len(list_of_states) + self.tensor = jnp.array(list_of_states).reshape(self.single_leg_radix, *self.radixes) + elif tensor != None: + self.tensor = tensor + self.single_leg_radix = single_leg_radix + self.num_qudits = num_qudits + self.num_of_legs = num_qudits + 1 + self.radixes = tuple(radixes if len(radixes) > 0 else [2] * num_qudits) + else: + raise "can't create the instance" + + def copy(self)->SingleLegSideTensor: + return self.__class__(tensor=self.tensor.copy(), num_qudits = self.num_qudits,radixes = self.radixes, single_leg_radix = self.single_leg_radix) + + @staticmethod + def calc_env(left:LHSTensor, right:RHSTensor, indexes_to_leave_open:Sequence[int]): + + #verify correct shape + assert left.radixes == right.radixes + + + left_contraction_indexs = list(range(left.num_qudits+1)) + right_contraction_indexs = list(range(left.num_qudits+1)) + + size_of_open = len(indexes_to_leave_open) + + for leg_num, i in enumerate(indexes_to_leave_open): + left_contraction_indexs[i+1] = size_of_open+leg_num+left.num_of_legs + right_contraction_indexs[i+1] = leg_num+left.num_of_legs + + + env_tensor = jnp.einsum( + left.tensor, left_contraction_indexs, + right.tensor, right_contraction_indexs + ) + env_mat = env_tensor.reshape((2**size_of_open, -1)) + + return env_mat + + +class RHSTensor(SingleLegSideTensor): + + def apply_left( + self, + utry: UnitaryMatrixJax, + location: tuple, + ) -> None: + + + """ + Apply the specified unitary on the left of this rhs tensor + + .. + .------. .-----. + 1 -| |---| | + 2 -| gate |---| . + '------' . . + . |- 0 + . . + n ------------| | + '-----' + + """ + + utry_tensor = utry.get_tensor_format() + utry_size = len(utry.radixes) + + + utry_tensor_indexs = [i+self.num_of_legs for i in range(utry_size)] + [1+l for l in location] + + rhs_tensor_indexes = list(range(self.num_of_legs)) + output_tensor_index = list(range(self.num_of_legs)) + + #matching the leg indexs of the utry + for i, loc in enumerate(location): + rhs_tensor_indexes[1 + loc] = i + self.num_of_legs + + self.tensor = jnp.einsum( + utry_tensor, utry_tensor_indexs, + self.tensor, rhs_tensor_indexes, output_tensor_index, + ) + + +class LHSTensor(SingleLegSideTensor): + + def apply_right( + self, + utry: UnitaryMatrixJax, + location: tuple, + ) -> None: + + + """ + Apply the specified unitary on the right of this lhs tensor. + + The reuslt looks like this + .-----. .------. + | |---| |- 1 + | |---| utry |- 2 + . . '------' + 0-| . + . . + . . + | |------------ n + '-----' + """ + + utry_tensor = utry.get_tensor_format() + utry_size = len(utry.radixes) + + + utry_tensor_indexs = [1+l for l in location] + [i+self.num_of_legs for i in range(utry_size)] + lhs_tensor_indexes = list(range(self.num_of_legs)) + output_tensor_index = list(range(self.num_of_legs)) + + #matching the leg indexs of the utry + for i, loc in enumerate(location): + lhs_tensor_indexes[1 + loc] = i + self.num_of_legs + + + self.tensor = jnp.einsum( + utry_tensor, utry_tensor_indexs, + self.tensor, lhs_tensor_indexes, output_tensor_index, + ) diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py new file mode 100644 index 0000000..4926880 --- /dev/null +++ b/tests/test_single_leg_tensor.py @@ -0,0 +1,82 @@ +#%% +import pytest +from random import randint, sample +import jax.numpy as jnp +from scipy.stats import unitary_group + +from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor +from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +from bqskit.ir.gates import HGate, CXGate + +@pytest.mark.parametrize("num_qubits, N", [(randint(2, 7), randint(3,10)) for _ in range(6)]) +def test_full_contraction_with_complex_conj(num_qubits, N): + random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + random_bras = [ket.T.conj() for ket in random_kets] + + rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + lhs = LHSTensor(list_of_states = random_kets, num_qudits = num_qubits) + + res = SingleLegSideTensor.calc_env(lhs, rhs, []).reshape(1)[0] + + assert jnp.isclose(res, N) + +@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) +def test_apply_left_H(num_qubits, N): + random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + random_bras = [ket.T.conj() for ket in random_kets] + + rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + orig = rhs.copy() + + H_mat = UnitaryMatrixJax(HGate().get_unitary()) + location = sorted(sample(range(num_qubits), 1)) + rhs.apply_left(H_mat, location) + assert not all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + rhs.apply_left(H_mat, location) + assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + +@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) +def test_apply_right_H(num_qubits, N): + random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + random_bras = [ket.T.conj() for ket in random_kets] + + rhs = LHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + orig = rhs.copy() + + H_mat = UnitaryMatrixJax(HGate().get_unitary()) + location = sorted(sample(range(num_qubits), 1)) + rhs.apply_right(H_mat, location) + assert not all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + rhs.apply_right(H_mat, location) + assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + +@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) +def test_apply_left_CX(num_qubits, N): + random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + random_bras = [ket.T.conj() for ket in random_kets] + + rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + orig = rhs.copy() + + H_mat = UnitaryMatrixJax(CXGate().get_unitary()) + location = sorted(sample(range(num_qubits), 2)) + rhs.apply_left(H_mat, location) + assert not all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + rhs.apply_left(H_mat, location) + assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + + +@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) +def test_apply_right_CX(num_qubits, N): + random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + random_bras = [ket.T.conj() for ket in random_kets] + + rhs = LHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + orig = rhs.copy() + + H_mat = UnitaryMatrixJax(CXGate().get_unitary()) + location = sorted(sample(range(num_qubits), 2)) + rhs.apply_right(H_mat, location) + assert not all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) + rhs.apply_right(H_mat, location) + assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) From b90baf48c9874b263f2a3df2163bafd97b24f550 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 14:36:59 -0700 Subject: [PATCH 03/59] also in the init file --- bqskitgpu/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bqskitgpu/__init__.py b/bqskitgpu/__init__.py index 01947e6..7eeda6a 100644 --- a/bqskitgpu/__init__.py +++ b/bqskitgpu/__init__.py @@ -1,4 +1,4 @@ __all__ = [ - 'qfactor_jax','unitary_acc', 'unitarybuilderjax', 'unitarymatrixjax' + 'qfactor_jax','unitary_acc', 'unitarybuilderjax', 'unitarymatrixjax','singlelegedtensor' ] From 34b0c7e62838ca0243c2ac8da8ed845a168b2c42 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 14:37:32 -0700 Subject: [PATCH 04/59] fixning a typo bug --- bqskitgpu/unitarymatrixjax.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bqskitgpu/unitarymatrixjax.py b/bqskitgpu/unitarymatrixjax.py index 092bc86..23760fd 100644 --- a/bqskitgpu/unitarymatrixjax.py +++ b/bqskitgpu/unitarymatrixjax.py @@ -64,7 +64,7 @@ def __init__( and type(input) is not jax.core.ShapedArray and not _from_tree ): - dim = np.prod(radixes) + dim = np.prod(self._radixes) self._utry = jnp.array(input, dtype=jnp.complex128).reshape( (dim, dim) , ) # make sure its a square matrix From c2be18e0da3867b672cc38b496808481087cb3d7 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 14:38:00 -0700 Subject: [PATCH 05/59] Declearing the correct reqired type --- bqskitgpu/unitarybuilderjax.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bqskitgpu/unitarybuilderjax.py b/bqskitgpu/unitarybuilderjax.py index a5daca7..5c9b9f5 100644 --- a/bqskitgpu/unitarybuilderjax.py +++ b/bqskitgpu/unitarybuilderjax.py @@ -120,7 +120,7 @@ def get_unitary(self, params: RealVector = []) -> UnitaryMatrixJax: return UnitaryMatrixJax(utry, self.radixes) def apply_right( self, - utry: UnitaryMatrix, + utry: UnitaryMatrixJax, location: CircuitLocationLike, inverse: bool = False, check_arguments: bool = True, @@ -139,7 +139,7 @@ def apply_right( '-----' Args: - utry (UnitaryMatrix): The unitary to apply. + utry (UnitaryMatrixJax): The unitary to apply. location (CircuitLocationLike): The qudits to apply the unitary on. @@ -207,7 +207,7 @@ def apply_right( def apply_left( self, - utry: UnitaryMatrix, + utry: UnitaryMatrixJax, location: CircuitLocationLike, inverse: bool = False, check_arguments: bool = True, From d62a78ae6ab6f20b87cb5042bef6aa5c2cd3731d Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 14:39:16 -0700 Subject: [PATCH 06/59] initial implementation of the QFactorQG --- bqskitgpu/qfactor_jax.py | 248 +++++++++++++++++++++++++++++++-------- 1 file changed, 197 insertions(+), 51 deletions(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index 0f27836..960d4b9 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -1,26 +1,33 @@ +#%% from __future__ import annotations - import functools import logging import os -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Sequence + -import jax -import jax.numpy as jnp import numpy as np import numpy.typing as npt from scipy.stats import unitary_group +import jax +import jax.numpy as jnp + from bqskit.ir.gates.constantgate import ConstantGate from bqskit.ir.gates.parameterized.u3 import U3Gate from bqskit.ir.gates.parameterized.unitary import VariableUnitaryGate from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix from bqskit.ir.opt.instantiater import Instantiater +from bqskit.ir.location import CircuitLocationLike +from bqskit.ir.location import CircuitLocation from bqskit.qis.state.state import StateVector from bqskit.qis.state.system import StateSystem from bqskitgpu.unitary_acc import VariableUnitaryGateAcc from bqskitgpu.unitarybuilderjax import UnitaryBuilderJax from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor + +from bqskit.ir.gates import CXGate if TYPE_CHECKING: from bqskit.ir.circuit import Circuit @@ -469,58 +476,29 @@ def _while_body_to_be_vmaped( ) untrys = untrys_as_matrixs - if 'All_ENVS' in os.environ: - - target_untry_builder_tensor = _initilize_circuit_tensor( - amount_of_qudits, target_radixes, locations, target.numpy, untrys, - ).tensor - - target_untry_builder = UnitaryBuilderJax( - amount_of_qudits, target_radixes, - tensor=target_untry_builder_tensor, - ) - - - iteration_count = iteration_count + 1 - - - untrys = _single_sweep_sim( - locations, gates, amount_of_gates, target_untry_builder, untrys, beta - ) - - target_untry_builder_tensor = _initilize_circuit_tensor( - amount_of_qudits, target_radixes, locations, target.numpy, untrys, - ).tensor - - target_untry_builder = UnitaryBuilderJax( - amount_of_qudits, target_radixes, - tensor=target_untry_builder_tensor, - ) - else: - # initilize every "n" iterations of the loop - operand_for_if = (untrys, target_untry_builder_tensor) - initilize_body = lambda x: _initilize_circuit_tensor( - amount_of_qudits, target_radixes, locations, target.numpy, x[0], - ).tensor - no_initilize_body = lambda x: x[1] - - target_untry_builder_tensor = jax.lax.cond( - iteration_count % n == 0, initilize_body, - no_initilize_body, operand_for_if, - ) + operand_for_if = (untrys, target_untry_builder_tensor) + initilize_body = lambda x: _initilize_circuit_tensor( + amount_of_qudits, target_radixes, locations, target.numpy, x[0], + ).tensor + no_initilize_body = lambda x: x[1] + + target_untry_builder_tensor = jax.lax.cond( + iteration_count % n == 0, initilize_body, + no_initilize_body, operand_for_if, + ) - target_untry_builder = UnitaryBuilderJax( - amount_of_qudits, target_radixes, - tensor=target_untry_builder_tensor, - ) + target_untry_builder = UnitaryBuilderJax( + amount_of_qudits, target_radixes, + tensor=target_untry_builder_tensor, + ) - iteration_count = iteration_count + 1 + iteration_count = iteration_count + 1 - target_untry_builder, untrys = _single_sweep( - locations, gates, amount_of_gates, target_untry_builder, untrys, beta - ) + target_untry_builder, untrys = _single_sweep( + locations, gates, amount_of_gates, target_untry_builder, untrys, beta + ) c2 = c1 dim = target_untry_builder.dim @@ -617,3 +595,171 @@ def while_body(var): 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ), ) + + + + + +def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, + # , diff_tol_a, + # diff_tol_r, plateau_windows_size, max_iters, min_iters, + # amount_of_starts, diff_tol_step_r, diff_tol_step, + beta=0): + + + amount_of_gates = len(gates) + + #### Generate N random states + random_states_ket = [] + random_states_bra = [] + for _ in range(N): + # We generate a random unitary and take its first column + random_states_ket.append(unitary_group.rvs(np.prod(radixes))[:,:1]) + random_states_bra.append(random_states_ket[-1].T.conj()) + + #### Compute A + A = RHSTensor(list_of_states = random_states_bra, num_qudits=num_qudits, radixes=radixes) + A.apply_left(target.T.conj(), range(num_qudits)) + + ### Until done.... + it = 1 + while True: + + ### Compute B + B = [LHSTensor(list_of_states = random_states_ket, num_qudits=num_qudits, radixes=radixes)] + for location, utry in zip(locations[:-1], untrys[:-1]): + B.append(B[-1].copy()) + B[-1].apply_right(utry, location) + + temp = B[-1].copy() + temp.apply_right(untrys[-1], locations[-1]) + cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A, [])[0])/N) + # print(f'initial {cost = }') + + ### iterate over every gate from right to left and update it + new_untrys = [None]*amount_of_gates + a:RHSTensor = A.copy() + for idx in reversed(range(amount_of_gates)): + b = B[idx] + gate = gates[idx] + location = locations[idx] + utry = untrys[idx] + if gate.num_params > 0: + # print(f"Updating {utry._utry = }") + env = SingleLegSideTensor.calc_env(b, a, location) + utry = gate.optimize(env.T, get_untry=True, prev_utry=utry, beta=beta) + # print(f"to {utry._utry = }") + + new_untrys[idx] = utry + a.apply_left(utry, location) + + untrys = new_untrys + + + cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B[0], a, [])[0])/N) + + if it%100 == 0: + print(f'{it = } {cost = }') + + if cost <= dist_tol or it > 30000: + print(f'{it = } {cost = }') + break + it+=1 + + + params = [] + for untry, gate in zip(untrys, gates): + if isinstance(gate, ConstantGate): + params.extend([]) + else: + params.extend( + gate.get_params(untry.numpy), + ) + + return np.array(params) + + +# %% +import numpy as np +from bqskit.ir.circuit import Circuit +from bqskit.ir.gates import VariableUnitaryGate +from bqskit.qis.unitary import UnitaryMatrix + +toffoli = np.array([ + [1, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1], + [0, 0, 0, 0, 0, 0, 1, 0], + ]) +target = UnitaryMatrixJax(toffoli) +circuit = Circuit(3) +circuit.append_gate(VariableUnitaryGate(2), [1, 2]) +circuit.append_gate(VariableUnitaryGate(2), [0, 2]) +circuit.append_gate(VariableUnitaryGate(2), [1, 2]) +circuit.append_gate(VariableUnitaryGate(2), [0, 2]) +circuit.append_gate(VariableUnitaryGate(2), [0, 1]) + + + +if False: + + circuit = Circuit(2) + if False: + circuit.append_gate(VariableUnitaryGate(2), [0,1]) + else: + circuit.append_gate(VariableUnitaryGate(1), [0]) + circuit.append_gate(VariableUnitaryGate(1), [1]) + circuit.append_gate(CXGate(), [0, 1]) + circuit.append_gate(VariableUnitaryGate(1), [0]) + circuit.append_gate(VariableUnitaryGate(1), [1]) + circuit.append_gate(CXGate(), [0, 1]) + circuit.append_gate(VariableUnitaryGate(1), [0]) + circuit.append_gate(VariableUnitaryGate(1), [1]) + circuit.append_gate(CXGate(), [0, 1]) + circuit.append_gate(VariableUnitaryGate(1), [0]) + circuit.append_gate(VariableUnitaryGate(1), [1]) + + target = UnitaryMatrixJax(unitary_group.rvs(4)) + +locations = tuple([op.location for op in circuit]) +for op in circuit: + g = op.gate + if isinstance(g, VariableUnitaryGate): + g.__class__ = VariableUnitaryGateAcc +gates = tuple([op.gate for op in circuit]) +pre_padding_untrys = [] +for gate in gates: + size_of_untry = 2**gate.num_qudits + + if isinstance(gate, VariableUnitaryGateAcc): + pre_padding_untrys.extend([ + UnitaryMatrixJax(unitary_group.rvs(size_of_untry)) for + _ in range(1) + ]) + else: + pre_padding_untrys.extend( [ + UnitaryMatrixJax(gate.get_unitary().numpy) for + _ in range(1) + ]) + + +# %% +# params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) +params = state_sample_sweep(6, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-10, beta=0) + +for op in circuit: + g = op.gate + if isinstance(g, VariableUnitaryGateAcc): + g.__class__ = VariableUnitaryGate +circuit.set_params(params) + +dist = circuit.get_unitary() +dist = circuit.get_unitary().get_distance_from(UnitaryMatrix(target.numpy), 1) +print(f'{dist = }') + + +# %% From 167d8cd99f0b343cc7a4cc25a1f7899eced842de Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 15:51:30 -0700 Subject: [PATCH 07/59] Adding more assertions --- bqskitgpu/singlelegedtensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bqskitgpu/singlelegedtensor.py b/bqskitgpu/singlelegedtensor.py index 100da43..93aca96 100644 --- a/bqskitgpu/singlelegedtensor.py +++ b/bqskitgpu/singlelegedtensor.py @@ -45,6 +45,7 @@ def calc_env(left:LHSTensor, right:RHSTensor, indexes_to_leave_open:Sequence[int #verify correct shape assert left.radixes == right.radixes + assert left.single_leg_radix == right.single_leg_radix, f'{left.single_leg_radix} != {right.single_leg_radix}' left_contraction_indexs = list(range(left.num_qudits+1)) From 88d25beab27e9823d1462487b3a5915fe611ce58 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 15:51:51 -0700 Subject: [PATCH 08/59] implemented the use of validations states --- bqskitgpu/qfactor_jax.py | 101 ++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index 960d4b9..5aa89df 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -9,6 +9,7 @@ import numpy as np import numpy.typing as npt from scipy.stats import unitary_group +import matplotlib.pyplot as plt import jax import jax.numpy as jnp @@ -600,45 +601,70 @@ def while_body(var): -def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, - # , diff_tol_a, - # diff_tol_r, plateau_windows_size, max_iters, min_iters, - # amount_of_starts, diff_tol_step_r, diff_tol_step, - beta=0): +def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, beta=0, training_states_kets = None, validation_states_kets = None): + training_costs = [] + validation_costs = [] + amount_of_gates = len(gates) - #### Generate N random states - random_states_ket = [] - random_states_bra = [] - for _ in range(N): - # We generate a random unitary and take its first column - random_states_ket.append(unitary_group.rvs(np.prod(radixes))[:,:1]) - random_states_bra.append(random_states_ket[-1].T.conj()) + training_states_bras = [] + if training_states_kets == None: + training_states_kets = [] + for _ in range(N): + # We generate a random unitary and take its first column + training_states_kets.append(unitary_group.rvs(np.prod(radixes))[:,:1]) + else: + assert N==len(training_states_kets) + + for ket in training_states_kets: + training_states_bras.append(ket.T.conj()) + + validation_states_bras = [] + if validation_states_kets == None: + validation_states_kets = [] + for _ in range(N//2): + # We generate a random unitary and take its first column + validation_states_kets.append(unitary_group.rvs(np.prod(radixes))[:,:1]) + + for ket in validation_states_kets: + validation_states_bras.append(ket.T.conj()) + + + + + #### Compute As + target_dagger = target.T.conj() + A_train = RHSTensor(list_of_states = training_states_bras, num_qudits=num_qudits, radixes=radixes) + A_train.apply_left(target_dagger, range(num_qudits)) + + A_val = RHSTensor(list_of_states = validation_states_bras, num_qudits=num_qudits, radixes=radixes) + A_val.apply_left(target_dagger, range(num_qudits)) - #### Compute A - A = RHSTensor(list_of_states = random_states_bra, num_qudits=num_qudits, radixes=radixes) - A.apply_left(target.T.conj(), range(num_qudits)) + B0_train = LHSTensor(list_of_states = training_states_kets, num_qudits=num_qudits, radixes=radixes) + B0_val = LHSTensor(list_of_states = validation_states_kets, num_qudits=num_qudits, radixes=radixes) ### Until done.... it = 1 while True: ### Compute B - B = [LHSTensor(list_of_states = random_states_ket, num_qudits=num_qudits, radixes=radixes)] + + B = [B0_train] for location, utry in zip(locations[:-1], untrys[:-1]): B.append(B[-1].copy()) B[-1].apply_right(utry, location) temp = B[-1].copy() temp.apply_right(untrys[-1], locations[-1]) - cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A, [])[0])/N) + training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A_train, [])[0])/N) # print(f'initial {cost = }') ### iterate over every gate from right to left and update it new_untrys = [None]*amount_of_gates - a:RHSTensor = A.copy() + a_train:RHSTensor = A_train.copy() + a_val:RHSTensor = A_val.copy() for idx in reversed(range(amount_of_gates)): b = B[idx] gate = gates[idx] @@ -646,27 +672,49 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, utry = untrys[idx] if gate.num_params > 0: # print(f"Updating {utry._utry = }") - env = SingleLegSideTensor.calc_env(b, a, location) + env = SingleLegSideTensor.calc_env(b, a_train, location) utry = gate.optimize(env.T, get_untry=True, prev_utry=utry, beta=beta) # print(f"to {utry._utry = }") new_untrys[idx] = utry - a.apply_left(utry, location) + a_train.apply_left(utry, location) + a_val.apply_left(utry, location) untrys = new_untrys - cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B[0], a, [])[0])/N) + training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_train, a_train, [])[0])/N) + validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N/2)) + + training_costs.append(training_cost) + validation_costs.append(validation_cost) - if it%100 == 0: - print(f'{it = } {cost = }') + if it%2 == 0: + print(f'{it = } {training_cost = }') + print(f'{it = } {validation_cost = }') - if cost <= dist_tol or it > 30000: - print(f'{it = } {cost = }') + if training_cost <= dist_tol or it > 3000: + print(f'{it = } {training_cost = }') break it+=1 + + plt.figure(figsize=(10, 6)) + plt.plot(training_costs, label='Training Costs', marker='o') + plt.plot(validation_costs, label='Validation Costs', marker='x') + + # Add labels and title + plt.xlabel('Epochs') + plt.ylabel('Cost') + plt.yscale('log') + plt.title('Training and Validation Costs') + plt.legend() + + # Show the plot + plt.grid(True) + plt.show() + params = [] for untry, gate in zip(untrys, gates): if isinstance(gate, ConstantGate): @@ -749,7 +797,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, # %% # params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) -params = state_sample_sweep(6, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-10, beta=0) +params = state_sample_sweep(8, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-8, beta=0) for op in circuit: g = op.gate @@ -757,7 +805,6 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, g.__class__ = VariableUnitaryGate circuit.set_params(params) -dist = circuit.get_unitary() dist = circuit.get_unitary().get_distance_from(UnitaryMatrix(target.numpy), 1) print(f'{dist = }') From 458fcd34edc9f39ae7b7ce297dbe4421830fcb79 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 15 Aug 2023 15:56:08 -0700 Subject: [PATCH 09/59] Adding a stoping critiria using the val cost --- bqskitgpu/qfactor_jax.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index 5aa89df..95c9212 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -693,6 +693,9 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, print(f'{it = } {training_cost = }') print(f'{it = } {validation_cost = }') + if it > 10 and validation_cost/10 > training_cost: + print("Stopped due to no improvment in validation set") + break if training_cost <= dist_tol or it > 3000: print(f'{it = } {training_cost = }') break @@ -797,7 +800,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, # %% # params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) -params = state_sample_sweep(8, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-8, beta=0) +params = state_sample_sweep(10, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-9, beta=0) for op in circuit: g = op.gate From c4bdf8a8a4b26043d922dbfa1e9db6c8493ffd52 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Wed, 6 Sep 2023 22:49:12 -0700 Subject: [PATCH 10/59] Refactoring the generation of random states --- bqskitgpu/qfactor_jax.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index 95c9212..3bd2953 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -611,10 +611,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, training_states_bras = [] if training_states_kets == None: - training_states_kets = [] - for _ in range(N): - # We generate a random unitary and take its first column - training_states_kets.append(unitary_group.rvs(np.prod(radixes))[:,:1]) + training_states_kets = generate_random_states(N, np.prod(radixes)) else: assert N==len(training_states_kets) @@ -623,10 +620,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, validation_states_bras = [] if validation_states_kets == None: - validation_states_kets = [] - for _ in range(N//2): - # We generate a random unitary and take its first column - validation_states_kets.append(unitary_group.rvs(np.prod(radixes))[:,:1]) + validation_states_kets = generate_random_states(N//4, np.prod(radixes)) for ket in validation_states_kets: validation_states_bras.append(ket.T.conj()) @@ -684,7 +678,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_train, a_train, [])[0])/N) - validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N/2)) + validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N//4)) training_costs.append(training_cost) validation_costs.append(validation_cost) @@ -693,7 +687,7 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, print(f'{it = } {training_cost = }') print(f'{it = } {validation_cost = }') - if it > 10 and validation_cost/10 > training_cost: + if it > 10 and validation_cost/32 > training_cost: print("Stopped due to no improvment in validation set") break if training_cost <= dist_tol or it > 3000: @@ -729,6 +723,31 @@ def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, return np.array(params) +def generate_random_states(amount_of_states, size_of_state): + """ + Generate a list of random state vectors (kets) using random unitary matrices. + + This function generates a specified number of random quantum state vectors + (kets) by creating random unitary matrices and extracting their first columns. + + Args: + amount_of_states (int): The number of random states to generate. + size_of_state (int): The dimension of each state vector (ket). + + Returns: + list of ndarrays: A list containing random quantum state vectors (kets). + Each ket is represented as a numpy ndarray of shape (size_of_state, 1). + """ + states_kets = [] + states_to_add = amount_of_states + while states_to_add > 0: + # We generate a random unitary and take its first column + rand_unitary = unitary_group.rvs(size_of_state) + states_to_add_in_step = min(states_to_add, size_of_state) + for i in range(states_to_add_in_step): + states_kets.append(rand_unitary[:, i:i+1]) + states_to_add -= states_to_add_in_step + return states_kets # %% import numpy as np From 93a4ce72b00828e6a86b0dd379c2c9a774842704 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 12 Sep 2023 16:00:26 -0700 Subject: [PATCH 11/59] Adding a seperate file for the state sampling --- bqskitgpu/qfactor_sample_jax.py | 310 ++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 bqskitgpu/qfactor_sample_jax.py diff --git a/bqskitgpu/qfactor_sample_jax.py b/bqskitgpu/qfactor_sample_jax.py new file mode 100644 index 0000000..337efe0 --- /dev/null +++ b/bqskitgpu/qfactor_sample_jax.py @@ -0,0 +1,310 @@ +from __future__ import annotations +import functools +import logging +import os +from typing import TYPE_CHECKING, Sequence + + +import numpy as np +import numpy.typing as npt +from scipy.stats import unitary_group +import matplotlib.pyplot as plt + +import jax +import jax.numpy as jnp + +from bqskit.ir.gates.constantgate import ConstantGate +from bqskit.ir.gates.parameterized.u3 import U3Gate +from bqskit.ir.gates.parameterized.unitary import VariableUnitaryGate +from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix +from bqskit.ir.opt.instantiater import Instantiater +from bqskit.ir.location import CircuitLocationLike +from bqskit.ir.location import CircuitLocation +from bqskit.qis.state.state import StateVector +from bqskit.qis.state.system import StateSystem +from bqskitgpu.unitary_acc import VariableUnitaryGateAcc +from bqskitgpu.unitarybuilderjax import UnitaryBuilderJax +from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor + +from bqskit.ir.gates import CXGate + +if TYPE_CHECKING: + from bqskit.ir.circuit import Circuit + from bqskit.qis.state.state import StateLike + from bqskit.qis.state.system import StateSystemLike + from bqskit.qis.unitary.unitarymatrix import UnitaryLike + +_logger = logging.getLogger(__name__) + +jax.config.update('jax_enable_x64', True) + + + +class QFactor_sample_jax(Instantiater): + + + def __init__( + self, + dist_tol: float = 1e-10, + max_iters: int = 100000, + min_iters: int = 1000, + beta: float = 0.0, + amount_of_validation_states : int = 2, + ): + + + if not isinstance(dist_tol, float) or dist_tol > 0.5: + raise TypeError('Invalid distance threshold.') + + if not isinstance(max_iters, int) or max_iters < 0: + raise TypeError('Invalid maximum number of iterations.') + + if not isinstance(min_iters, int) or min_iters < 0: + raise TypeError('Invalid minimum number of iterations.') + + + self.dist_tol = dist_tol + self.max_iters = max_iters + self.min_iters = min_iters + + self.beta = beta + self.amount_of_validation_states = amount_of_validation_states + + + def instantiate( + self, + circuit: Circuit, + target: UnitaryMatrix | StateVector | StateSystem, + x0: npt.NDArray[np.float64], + ) -> npt.NDArray[np.float64]: + + return self.multi_start_instantiate(circuit, target, 1) + + def multi_start_instantiate_inplace( + self, + circuit: Circuit, + target: UnitaryLike | StateLike | StateSystemLike, + num_starts: int, + ) -> None: + """ + Instantiate `circuit` to best implement `target` with multiple starts. + + See :func:`multi_start_instantiate` for more info. + + Notes: + This method is a version of :func:`multi_start_instantiate` + that modifies `circuit` in place rather than returning a copy. + """ + target = self.check_target(target) + params = self.multi_start_instantiate(circuit, target, num_starts) + circuit.set_params(params) + + + async def multi_start_instantiate_async( + self, + circuit: Circuit, + target: UnitaryLike | StateLike | StateSystemLike, + num_starts: int, + ) -> npt.NDArray[np.float64]: + + return self.multi_start_instantiate(circuit, target, num_starts) + + + + + def multi_start_instantiate( + self, + circuit: Circuit, + target: UnitaryLike | StateLike | StateSystemLike, + num_starts: int, + ) -> npt.NDArray[np.float64]: + if len(circuit) == 0: + return [] + + circuit = circuit.copy() + + # A very ugly casting + for op in circuit: + g = op.gate + if isinstance(g, VariableUnitaryGate): + g.__class__ = VariableUnitaryGateAcc + + + target = UnitaryMatrixJax(self.check_target(target)) + locations = tuple([op.location for op in circuit]) + gates = tuple([op.gate for op in circuit]) + untrys = [] + + for gate in gates: + size_of_untry = 2**gate.num_qudits + + if isinstance(gate, VariableUnitaryGateAcc): + pre_padding_untrys = [ + unitary_group.rvs(size_of_untry) for + _ in range(num_starts) + ] + else: + pre_padding_untrys = [ + gate.get_unitary().numpy for + _ in range(num_starts) + ] + + untrys.append(pre_padding_untrys) + + untrys = jnp.array(np.stack(untrys, axis=1)) + + + + def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, max_iters:int = 1000, beta:float=0.0, training_states_kets = None, validation_states_kets = None): + + + training_costs = [] + validation_costs = [] + + amount_of_gates = len(gates) + + training_states_bras = [] + if training_states_kets == None: + training_states_kets = QFactor_sample_jax.generate_random_states(N, np.prod(radixes)) + else: + assert N==len(training_states_kets) + + for ket in training_states_kets: + training_states_bras.append(ket.T.conj()) + + validation_states_bras = [] + if validation_states_kets == None: + validation_states_kets = QFactor_sample_jax.generate_random_states(N//4, np.prod(radixes)) + + for ket in validation_states_kets: + validation_states_bras.append(ket.T.conj()) + + + + + #### Compute As + target_dagger = target.T.conj() + A_train = RHSTensor(list_of_states = training_states_bras, num_qudits=num_qudits, radixes=radixes) + A_train.apply_left(target_dagger, range(num_qudits)) + + A_val = RHSTensor(list_of_states = validation_states_bras, num_qudits=num_qudits, radixes=radixes) + A_val.apply_left(target_dagger, range(num_qudits)) + + B0_train = LHSTensor(list_of_states = training_states_kets, num_qudits=num_qudits, radixes=radixes) + B0_val = LHSTensor(list_of_states = validation_states_kets, num_qudits=num_qudits, radixes=radixes) + + ### Until done.... + it = 1 + while True: + + ### Compute B + + B = [B0_train] + for location, utry in zip(locations[:-1], untrys[:-1]): + B.append(B[-1].copy()) + B[-1].apply_right(utry, location) + + temp = B[-1].copy() + temp.apply_right(untrys[-1], locations[-1]) + training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A_train, [])[0])/N) + # print(f'initial {cost = }') + + ### iterate over every gate from right to left and update it + new_untrys = [None]*amount_of_gates + a_train:RHSTensor = A_train.copy() + a_val:RHSTensor = A_val.copy() + for idx in reversed(range(amount_of_gates)): + b = B[idx] + gate = gates[idx] + location = locations[idx] + utry = untrys[idx] + if gate.num_params > 0: + # print(f"Updating {utry._utry = }") + env = SingleLegSideTensor.calc_env(b, a_train, location) + utry = gate.optimize(env.T, get_untry=True, prev_utry=utry, beta=beta) + # print(f"to {utry._utry = }") + + new_untrys[idx] = utry + a_train.apply_left(utry, location) + a_val.apply_left(utry, location) + + untrys = new_untrys + + + training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_train, a_train, [])[0])/N) + validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N//4)) + + training_costs.append(training_cost) + validation_costs.append(validation_cost) + + if it%100 == 0: + print(f'{it = } {training_cost = }') + print(f'{it = } {validation_cost = }') + + if it > 10 and validation_cost/32 > training_cost: + print("Stopped due to no improvment in validation set") + break + if training_cost <= dist_tol or it > 3000: + print(f'{it = } {training_cost = }') + break + it+=1 + + + + plt.figure(figsize=(10, 6)) + plt.plot(training_costs, label='Training Costs', marker='o') + plt.plot(validation_costs, label='Validation Costs', marker='x') + + # Add labels and title + plt.xlabel('Epochs') + plt.ylabel('Cost') + plt.yscale('log') + plt.title('Training and Validation Costs') + plt.legend() + + # Show the plot + plt.grid(True) + plt.show() + + params = [] + for untry, gate in zip(untrys, gates): + if isinstance(gate, ConstantGate): + params.extend([]) + else: + params.extend( + gate.get_params(untry.numpy), + ) + + return np.array(params) + + + + + + @staticmethod + def generate_random_states(amount_of_states, size_of_state): + """ + Generate a list of random state vectors (kets) using random unitary matrices. + + This function generates a specified number of random quantum state vectors + (kets) by creating random unitary matrices and extracting their first columns. + + Args: + amount_of_states (int): The number of random states to generate. + size_of_state (int): The dimension of each state vector (ket). + + Returns: + list of ndarrays: A list containing random quantum state vectors (kets). + Each ket is represented as a numpy ndarray of shape (size_of_state, 1). + """ + states_kets = [] + states_to_add = amount_of_states + while states_to_add > 0: + # We generate a random unitary and take its columns + rand_unitary = unitary_group.rvs(size_of_state) + states_to_add_in_step = min(states_to_add, size_of_state) + for i in range(states_to_add_in_step): + states_kets.append(rand_unitary[:, i:i+1]) + states_to_add -= states_to_add_in_step + return states_kets \ No newline at end of file From c1b9873d1895177685ce2ce6564e63dd25a7dc75 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 25 Sep 2023 13:37:51 -0700 Subject: [PATCH 12/59] Removing from the main file --- bqskitgpu/qfactor_jax.py | 156 ++------------------------------------- 1 file changed, 7 insertions(+), 149 deletions(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index 3bd2953..d9c0a40 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -601,154 +601,8 @@ def while_body(var): -def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, beta=0, training_states_kets = None, validation_states_kets = None): - training_costs = [] - validation_costs = [] - - amount_of_gates = len(gates) - - training_states_bras = [] - if training_states_kets == None: - training_states_kets = generate_random_states(N, np.prod(radixes)) - else: - assert N==len(training_states_kets) - - for ket in training_states_kets: - training_states_bras.append(ket.T.conj()) - - validation_states_bras = [] - if validation_states_kets == None: - validation_states_kets = generate_random_states(N//4, np.prod(radixes)) - - for ket in validation_states_kets: - validation_states_bras.append(ket.T.conj()) - - - - - #### Compute As - target_dagger = target.T.conj() - A_train = RHSTensor(list_of_states = training_states_bras, num_qudits=num_qudits, radixes=radixes) - A_train.apply_left(target_dagger, range(num_qudits)) - - A_val = RHSTensor(list_of_states = validation_states_bras, num_qudits=num_qudits, radixes=radixes) - A_val.apply_left(target_dagger, range(num_qudits)) - - B0_train = LHSTensor(list_of_states = training_states_kets, num_qudits=num_qudits, radixes=radixes) - B0_val = LHSTensor(list_of_states = validation_states_kets, num_qudits=num_qudits, radixes=radixes) - - ### Until done.... - it = 1 - while True: - - ### Compute B - - B = [B0_train] - for location, utry in zip(locations[:-1], untrys[:-1]): - B.append(B[-1].copy()) - B[-1].apply_right(utry, location) - - temp = B[-1].copy() - temp.apply_right(untrys[-1], locations[-1]) - training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A_train, [])[0])/N) - # print(f'initial {cost = }') - - ### iterate over every gate from right to left and update it - new_untrys = [None]*amount_of_gates - a_train:RHSTensor = A_train.copy() - a_val:RHSTensor = A_val.copy() - for idx in reversed(range(amount_of_gates)): - b = B[idx] - gate = gates[idx] - location = locations[idx] - utry = untrys[idx] - if gate.num_params > 0: - # print(f"Updating {utry._utry = }") - env = SingleLegSideTensor.calc_env(b, a_train, location) - utry = gate.optimize(env.T, get_untry=True, prev_utry=utry, beta=beta) - # print(f"to {utry._utry = }") - - new_untrys[idx] = utry - a_train.apply_left(utry, location) - a_val.apply_left(utry, location) - - untrys = new_untrys - - - training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_train, a_train, [])[0])/N) - validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N//4)) - - training_costs.append(training_cost) - validation_costs.append(validation_cost) - - if it%2 == 0: - print(f'{it = } {training_cost = }') - print(f'{it = } {validation_cost = }') - - if it > 10 and validation_cost/32 > training_cost: - print("Stopped due to no improvment in validation set") - break - if training_cost <= dist_tol or it > 3000: - print(f'{it = } {training_cost = }') - break - it+=1 - - - - plt.figure(figsize=(10, 6)) - plt.plot(training_costs, label='Training Costs', marker='o') - plt.plot(validation_costs, label='Validation Costs', marker='x') - - # Add labels and title - plt.xlabel('Epochs') - plt.ylabel('Cost') - plt.yscale('log') - plt.title('Training and Validation Costs') - plt.legend() - - # Show the plot - plt.grid(True) - plt.show() - - params = [] - for untry, gate in zip(untrys, gates): - if isinstance(gate, ConstantGate): - params.extend([]) - else: - params.extend( - gate.get_params(untry.numpy), - ) - - return np.array(params) - -def generate_random_states(amount_of_states, size_of_state): - """ - Generate a list of random state vectors (kets) using random unitary matrices. - - This function generates a specified number of random quantum state vectors - (kets) by creating random unitary matrices and extracting their first columns. - - Args: - amount_of_states (int): The number of random states to generate. - size_of_state (int): The dimension of each state vector (ket). - - Returns: - list of ndarrays: A list containing random quantum state vectors (kets). - Each ket is represented as a numpy ndarray of shape (size_of_state, 1). - """ - states_kets = [] - states_to_add = amount_of_states - while states_to_add > 0: - # We generate a random unitary and take its first column - rand_unitary = unitary_group.rvs(size_of_state) - states_to_add_in_step = min(states_to_add, size_of_state) - for i in range(states_to_add_in_step): - states_kets.append(rand_unitary[:, i:i+1]) - states_to_add -= states_to_add_in_step - return states_kets - # %% import numpy as np from bqskit.ir.circuit import Circuit @@ -775,7 +629,7 @@ def generate_random_states(amount_of_states, size_of_state): -if False: +if True: circuit = Circuit(2) if False: @@ -818,8 +672,12 @@ def generate_random_states(amount_of_states, size_of_state): # %% -# params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) -params = state_sample_sweep(10, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-9, beta=0) +for op in circuit: + g = op.gate + if isinstance(g, VariableUnitaryGate): + g.__class__ = VariableUnitaryGateAcc +params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) +# params = state_sample_sweep(10, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-9, beta=0) for op in circuit: g = op.gate From 9f413c984e4a37c423e1ee46ad5f8d5a5cb4e004 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 2 Oct 2023 22:17:30 -0700 Subject: [PATCH 13/59] Before pre-commits fixs --- bqskitgpu/qfactor_sample_jax.py | 471 ++++++++++++++++++++------------ 1 file changed, 301 insertions(+), 170 deletions(-) diff --git a/bqskitgpu/qfactor_sample_jax.py b/bqskitgpu/qfactor_sample_jax.py index 337efe0..eec7184 100644 --- a/bqskitgpu/qfactor_sample_jax.py +++ b/bqskitgpu/qfactor_sample_jax.py @@ -1,33 +1,34 @@ from __future__ import annotations -import functools + import logging import os -from typing import TYPE_CHECKING, Sequence - +from typing import TYPE_CHECKING +import jax +import jax.numpy as jnp +import jax.numpy.logical_and as jand +import jax.numpy.logical_not as jnot +import jax.numpy.logical_or as jor import numpy as np import numpy.typing as npt +from bqskit.ir import CircuitLocation +from bqskit.ir import Gate +from bqskit.ir.gates import ConstantGate +from bqskit.ir.gates import VariableUnitaryGate +from bqskit.ir.opt import Instantiater +from bqskit.qis import UnitaryMatrix +from bqskit.qis.state import StateSystem +from bqskit.qis.state import StateVector +from jax import Array from scipy.stats import unitary_group -import matplotlib.pyplot as plt - -import jax -import jax.numpy as jnp -from bqskit.ir.gates.constantgate import ConstantGate -from bqskit.ir.gates.parameterized.u3 import U3Gate -from bqskit.ir.gates.parameterized.unitary import VariableUnitaryGate -from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix -from bqskit.ir.opt.instantiater import Instantiater -from bqskit.ir.location import CircuitLocationLike -from bqskit.ir.location import CircuitLocation -from bqskit.qis.state.state import StateVector -from bqskit.qis.state.system import StateSystem +from bqskitgpu.qfactor_jax import _apply_padding_and_flatten +from bqskitgpu.qfactor_jax import _remove_padding_and_create_matrix +from bqskitgpu.singlelegedtensor import LHSTensor +from bqskitgpu.singlelegedtensor import RHSTensor +from bqskitgpu.singlelegedtensor import SingleLegSideTensor from bqskitgpu.unitary_acc import VariableUnitaryGateAcc -from bqskitgpu.unitarybuilderjax import UnitaryBuilderJax from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax -from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor - -from bqskit.ir.gates import CXGate if TYPE_CHECKING: from bqskit.ir.circuit import Circuit @@ -40,19 +41,18 @@ jax.config.update('jax_enable_x64', True) - class QFactor_sample_jax(Instantiater): - def __init__( - self, - dist_tol: float = 1e-10, - max_iters: int = 100000, - min_iters: int = 1000, - beta: float = 0.0, - amount_of_validation_states : int = 2, - ): - + self, + dist_tol: float = 1e-10, + max_iters: int = 100000, + min_iters: int = 1000, + beta: float = 0.0, + amount_of_validation_states: int = 2, + num_params_coeff: float = 1, + overtrain_ratio: float = 1 / 32, + ): if not isinstance(dist_tol, float) or dist_tol > 0.5: raise TypeError('Invalid distance threshold.') @@ -63,21 +63,21 @@ def __init__( if not isinstance(min_iters, int) or min_iters < 0: raise TypeError('Invalid minimum number of iterations.') - self.dist_tol = dist_tol self.max_iters = max_iters self.min_iters = min_iters self.beta = beta self.amount_of_validation_states = amount_of_validation_states - + self.num_params_coeff = num_params_coeff + self.overtrain_ratio = overtrain_ratio def instantiate( - self, - circuit: Circuit, - target: UnitaryMatrix | StateVector | StateSystem, - x0: npt.NDArray[np.float64], - ) -> npt.NDArray[np.float64]: + self, + circuit: Circuit, + target: UnitaryMatrix | StateVector | StateSystem, + x0: npt.NDArray[np.float64], + ) -> npt.NDArray[np.float64]: return self.multi_start_instantiate(circuit, target, 1) @@ -100,18 +100,14 @@ def multi_start_instantiate_inplace( params = self.multi_start_instantiate(circuit, target, num_starts) circuit.set_params(params) - async def multi_start_instantiate_async( self, circuit: Circuit, target: UnitaryLike | StateLike | StateSystemLike, num_starts: int, ) -> npt.NDArray[np.float64]: - - return self.multi_start_instantiate(circuit, target, num_starts) - - + return self.multi_start_instantiate(circuit, target, num_starts) def multi_start_instantiate( self, @@ -120,7 +116,7 @@ def multi_start_instantiate( num_starts: int, ) -> npt.NDArray[np.float64]: if len(circuit) == 0: - return [] + return np.array([]) circuit = circuit.copy() @@ -130,10 +126,11 @@ def multi_start_instantiate( if isinstance(g, VariableUnitaryGate): g.__class__ = VariableUnitaryGateAcc - target = UnitaryMatrixJax(self.check_target(target)) locations = tuple([op.location for op in circuit]) gates = tuple([op.gate for op in circuit]) + biggest_gate_size = max(gate.num_qudits for gate in gates) + untrys = [] for gate in gates: @@ -150,142 +147,75 @@ def multi_start_instantiate( _ in range(num_starts) ] - untrys.append(pre_padding_untrys) + untrys.append([ + _apply_padding_and_flatten( + pre_padd, gate, biggest_gate_size, + ) for pre_padd in pre_padding_untrys + ]) untrys = jnp.array(np.stack(untrys, axis=1)) - - - def state_sample_sweep(N:int, target:UnitaryMatrixJax, locations, gates, untrys, num_qudits, radixes, dist_tol, max_iters:int = 1000, beta:float=0.0, training_states_kets = None, validation_states_kets = None): - - - training_costs = [] - validation_costs = [] - - amount_of_gates = len(gates) - - training_states_bras = [] - if training_states_kets == None: - training_states_kets = QFactor_sample_jax.generate_random_states(N, np.prod(radixes)) + amount_of_trainng_states = 0 + for g in gates: + amount_of_trainng_states += self.num_params_coeff * g.num_params + + amount_of_trainng_states = np.round(amount_of_trainng_states) + + training_states_kets = self.generate_random_states( + amount_of_trainng_states, + ) + validation_states_kets = self.generate_random_states( + self.amount_of_validation_states, + ) + + final_untrys, training_costs, validation_costs, iteration_counts = _jited_loop_vmaped_state_sample_sweep( + target, locations, gates, untrys, + self.dist_tol, self.max_iters, self.beta, + training_states_kets, validation_states_kets, + ) + + it = iteration_counts[0] + untrys = final_untrys + best_start = jnp.argmin(training_costs) + + if any(training_costs < self.dist_tol): + _logger.debug( + f'Terminated: {it} c1 = {training_costs} <= dist_tol.\n' + f'Best start is {best_start}', + ) + elif all(validation_costs > self.overtrain_ratio * training_costs): + _logger.debug( + f'Terminated: {it} overtraining detected in all multistarts', + ) + elif it >= self.max_iters: + _logger.debug('Terminated: iteration limit reached.') else: - assert N==len(training_states_kets) - - for ket in training_states_kets: - training_states_bras.append(ket.T.conj()) - - validation_states_bras = [] - if validation_states_kets == None: - validation_states_kets = QFactor_sample_jax.generate_random_states(N//4, np.prod(radixes)) - - for ket in validation_states_kets: - validation_states_bras.append(ket.T.conj()) - - - - - #### Compute As - target_dagger = target.T.conj() - A_train = RHSTensor(list_of_states = training_states_bras, num_qudits=num_qudits, radixes=radixes) - A_train.apply_left(target_dagger, range(num_qudits)) - - A_val = RHSTensor(list_of_states = validation_states_bras, num_qudits=num_qudits, radixes=radixes) - A_val.apply_left(target_dagger, range(num_qudits)) - - B0_train = LHSTensor(list_of_states = training_states_kets, num_qudits=num_qudits, radixes=radixes) - B0_val = LHSTensor(list_of_states = validation_states_kets, num_qudits=num_qudits, radixes=radixes) - - ### Until done.... - it = 1 - while True: - - ### Compute B - - B = [B0_train] - for location, utry in zip(locations[:-1], untrys[:-1]): - B.append(B[-1].copy()) - B[-1].apply_right(utry, location) - - temp = B[-1].copy() - temp.apply_right(untrys[-1], locations[-1]) - training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(temp, A_train, [])[0])/N) - # print(f'initial {cost = }') - - ### iterate over every gate from right to left and update it - new_untrys = [None]*amount_of_gates - a_train:RHSTensor = A_train.copy() - a_val:RHSTensor = A_val.copy() - for idx in reversed(range(amount_of_gates)): - b = B[idx] - gate = gates[idx] - location = locations[idx] - utry = untrys[idx] - if gate.num_params > 0: - # print(f"Updating {utry._utry = }") - env = SingleLegSideTensor.calc_env(b, a_train, location) - utry = gate.optimize(env.T, get_untry=True, prev_utry=utry, beta=beta) - # print(f"to {utry._utry = }") - - new_untrys[idx] = utry - a_train.apply_left(utry, location) - a_val.apply_left(utry, location) - - untrys = new_untrys - - - training_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_train, a_train, [])[0])/N) - validation_cost = 2*(1-jnp.real(SingleLegSideTensor.calc_env(B0_val, a_val, [])[0])/(N//4)) - - training_costs.append(training_cost) - validation_costs.append(validation_cost) - - if it%100 == 0: - print(f'{it = } {training_cost = }') - print(f'{it = } {validation_cost = }') - - if it > 10 and validation_cost/32 > training_cost: - print("Stopped due to no improvment in validation set") - break - if training_cost <= dist_tol or it > 3000: - print(f'{it = } {training_cost = }') - break - it+=1 - - - - plt.figure(figsize=(10, 6)) - plt.plot(training_costs, label='Training Costs', marker='o') - plt.plot(validation_costs, label='Validation Costs', marker='x') - - # Add labels and title - plt.xlabel('Epochs') - plt.ylabel('Cost') - plt.yscale('log') - plt.title('Training and Validation Costs') - plt.legend() - - # Show the plot - plt.grid(True) - plt.show() + _logger.error( + f'Terminated with no good reason after {it} iterstion ' + f'with c1s {training_costs}.', + ) params = [] - for untry, gate in zip(untrys, gates): - if isinstance(gate, ConstantGate): + for untry, gate in zip(untrys[best_start], gates): + if isinstance(gate, ConstantGate): params.extend([]) - else: + else: params.extend( - gate.get_params(untry.numpy), - ) - - return np.array(params) - - - + gate.get_params( + _remove_padding_and_create_matrix(untry, gate), + ), + ) + return np.array(params) @staticmethod - def generate_random_states(amount_of_states, size_of_state): + def generate_random_states( + amount_of_states: int, + size_of_state: int, + ) -> list[npt.NDArray]: """ - Generate a list of random state vectors (kets) using random unitary matrices. + Generate a list of random state vectors (kets) using random unitary + matrices. This function generates a specified number of random quantum state vectors (kets) by creating random unitary matrices and extracting their first columns. @@ -305,6 +235,207 @@ def generate_random_states(amount_of_states, size_of_state): rand_unitary = unitary_group.rvs(size_of_state) states_to_add_in_step = min(states_to_add, size_of_state) for i in range(states_to_add_in_step): - states_kets.append(rand_unitary[:, i:i+1]) + states_kets.append(rand_unitary[:, i:i + 1]) states_to_add -= states_to_add_in_step - return states_kets \ No newline at end of file + return states_kets + + +def _loop_vmaped_state_sample_sweep( + target: UnitaryMatrixJax, num_qudits: int, radixes: tuple[int, ...], + locations: tuple[CircuitLocation, ...], + gates: tuple[Gate, ...], untrys: Array, + dist_tol: float, max_iters: int, beta: float, + amount_of_starts: int, min_iters: int, + overtrian_ratio: float, + training_states_kets: Array, + validation_states_kets: Array, +) -> tuple[Array, Array[float], Array[float], Array[int]]: + + validation_states_bras = jax.vmap( + lambda ket: ket.T.conj(), + )(validation_states_kets) + + training_states_bras = jax.vmap( + lambda ket: ket.T.conj(), + )(training_states_kets) + + # Calculate the A and B0 tensor + target_dagger = target.T.conj() + A_train = RHSTensor( + list_of_states=training_states_bras, + num_qudits=num_qudits, radixes=radixes, + ) + A_train.apply_left(target_dagger, range(num_qudits)) + + A_val = RHSTensor( + list_of_states=validation_states_bras, + num_qudits=num_qudits, radixes=radixes, + ) + A_val.apply_left(target_dagger, range(num_qudits)) + + B0_train = LHSTensor( + list_of_states=training_states_kets, + num_qudits=num_qudits, radixes=radixes, + ) + B0_val = LHSTensor( + list_of_states=validation_states_kets, + num_qudits=num_qudits, radixes=radixes, + ) + + # In JAX the body of a while must be a function that accepet and returns + # the same type, and also the check should be a function that accepts it + # and return a boolean + + def should_continue(loop_var: tuple): + _, training_costs, validation_costs, iteration_counts = loop_var + + any_reached_required_tol = jnp.any( + jax.vmap( + lambda cost: cost <= dist_tol, + training_costs, + ), + ) + reached_max_iteration = iteration_counts[0] > max_iters + + above_min_iteration = iteration_counts[0] > min_iters + + any_reached_over_training = jnp.any( + jax.vmap( + lambda train_cost, val_cost: + val_cost > overtrian_ratio * train_cost, + (training_costs, validation_costs), + ), + ) + + return jnot( + jor( + any_reached_required_tol, + jor( + reached_max_iteration, + jand( + above_min_iteration, + any_reached_over_training, + ), + ), + ), + ) + + def _while_body_to_be_vmaped(loop_var: tuple): + + untrys, training_cost, validation_cost, iteration_count = loop_var + + untrys_as_matrixs: list[UnitaryMatrixJax] = [] + for gate_index, gate in enumerate(gates): + untrys_as_matrixs.append( + UnitaryMatrixJax( + _remove_padding_and_create_matrix( + untrys[gate_index], gate, + ), gate.radixes, + ), + ) + + untrys_as_matrixs, training_cost, validation_cost = state_sample_single_sweep( + locations, gates, untrys_as_matrixs, + beta, A_train, A_val, B0_train, B0_val, + ) + + iteration_count += 1 + + biggest_gate_size = max(gate.num_qudits for gate in gates) + final_untrys_padded = jnp.array([ + _apply_padding_and_flatten( + untry.numpy.flatten( + ), gate, biggest_gate_size, + ) for untry, gate in zip(untrys, gates) + ]) + + return ( + final_untrys_padded, training_cost, validation_cost, + iteration_count, + ) + + while_body_vmaped = jax.vmap(_while_body_to_be_vmaped) + + initial_loop_var = ( + untrys, + jnp.ones(amount_of_starts), # train_cost + jnp.ones(amount_of_starts), # val_cost + jnp.zeros(amount_of_starts), # iter_count + ) + + r = jax.lax.while_loop(should_continue, while_body_vmaped, initial_loop_var) + final_untrys, training_costs, validation_costs, iteration_counts = r + + return final_untrys, training_costs, validation_costs, iteration_counts + + +def state_sample_single_sweep( + locations: tuple[CircuitLocation, ...], + gates: tuple[Gate, ...], + untrys: list[UnitaryMatrixJax], beta: float, + A_train: RHSTensor, A_val: RHSTensor, + B0_train: LHSTensor, B0_val: LHSTensor, +) -> list[UnitaryMatrixJax] | float | float: + + amount_of_gates = len(gates) + B = [B0_train] + for location, utry in zip(locations[:-1], untrys[:-1]): + B.append(B[-1].copy()) + B[-1].apply_right(utry, location) + + temp = B[-1].copy() + temp.apply_right(untrys[-1], locations[-1]) + training_cost = 2 * ( + 1 - jnp.real( + SingleLegSideTensor.calc_env( + temp, + A_train, [], + )[0], + ) / A_train.single_leg_radix + ) + + # iterate over every gate from right to left and update it + new_untrys = [None] * amount_of_gates + a_train: RHSTensor = A_train.copy() + a_val: RHSTensor = A_val.copy() + for idx in reversed(range(amount_of_gates)): + b = B[idx] + gate = gates[idx] + location = locations[idx] + utry = untrys[idx] + if gate.num_params > 0: + env = SingleLegSideTensor.calc_env(b, a_train, location) + utry = gate.optimize( + env.T, get_untry=True, + prev_utry=utry, beta=beta, + ) + + new_untrys[idx] = utry + a_train.apply_left(utry, location) + a_val.apply_left(utry, location) + + untrys = new_untrys + + training_cost = calc_cost(A_train, B0_train, a_train) + + validation_cost = calc_cost(A_val, B0_val, a_val) + + return untrys, training_cost, validation_cost + + +def calc_cost(A: RHSTensor, B0: LHSTensor, a: RHSTensor) -> float: + return 2 * ( + 1 - jnp.real( + SingleLegSideTensor.calc_env(B0, a, [])[0], + ) / A.single_leg_radix + ) + + +if 'NO_JIT_QFACTOR' in os.environ: + _jited_loop_vmaped_state_sample_sweep = _loop_vmaped_state_sample_sweep +else: + _jited_loop_vmaped_state_sample_sweep = jax.jit( + _loop_vmaped_state_sample_sweep, static_argnums=( + 1, 2, 3, 4, 6, 7, 8, 9, 10, + ), + ) From 52afa012cdeec6eb13c117e00019028b37702dc7 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 2 Oct 2023 22:22:39 -0700 Subject: [PATCH 14/59] restoring qfactor_jax --- bqskitgpu/qfactor_jax.py | 380 +++++++++++++++++---------------------- 1 file changed, 162 insertions(+), 218 deletions(-) diff --git a/bqskitgpu/qfactor_jax.py b/bqskitgpu/qfactor_jax.py index d9c0a40..7a67a53 100644 --- a/bqskitgpu/qfactor_jax.py +++ b/bqskitgpu/qfactor_jax.py @@ -1,34 +1,28 @@ -#%% from __future__ import annotations + import functools import logging import os -from typing import TYPE_CHECKING, Sequence - - -import numpy as np -import numpy.typing as npt -from scipy.stats import unitary_group -import matplotlib.pyplot as plt +from typing import Sequence +from typing import TYPE_CHECKING import jax import jax.numpy as jnp - +import numpy as np +import numpy.typing as npt +from bqskit.ir import CircuitLocation +from bqskit.ir import Gate from bqskit.ir.gates.constantgate import ConstantGate from bqskit.ir.gates.parameterized.u3 import U3Gate from bqskit.ir.gates.parameterized.unitary import VariableUnitaryGate -from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix from bqskit.ir.opt.instantiater import Instantiater -from bqskit.ir.location import CircuitLocationLike -from bqskit.ir.location import CircuitLocation -from bqskit.qis.state.state import StateVector -from bqskit.qis.state.system import StateSystem +from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix +from jax import Array +from scipy.stats import unitary_group + from bqskitgpu.unitary_acc import VariableUnitaryGateAcc from bqskitgpu.unitarybuilderjax import UnitaryBuilderJax from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax -from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor - -from bqskit.ir.gates import CXGate if TYPE_CHECKING: from bqskit.ir.circuit import Circuit @@ -88,17 +82,16 @@ def __init__( def instantiate( self, circuit: Circuit, - target: UnitaryMatrix | StateVector | StateSystem, + target: UnitaryLike, x0: npt.NDArray[np.float64], ) -> npt.NDArray[np.float64]: return self.multi_start_instantiate(circuit, target, 1) - def multi_start_instantiate_inplace( self, circuit: Circuit, - target: UnitaryLike | StateLike | StateSystemLike, + target: UnitaryLike, num_starts: int, ) -> None: """ @@ -110,20 +103,17 @@ def multi_start_instantiate_inplace( This method is a version of :func:`multi_start_instantiate` that modifies `circuit` in place rather than returning a copy. """ - target = self.check_target(target) - params = self.multi_start_instantiate(circuit, target, num_starts) + target_mat: UnitaryMatrix = self.check_target(target) + params = self.multi_start_instantiate(circuit, target_mat, num_starts) circuit.set_params(params) - - - async def multi_start_instantiate_async( self, circuit: Circuit, - target: UnitaryLike | StateLike | StateSystemLike, + target: UnitaryLike, num_starts: int, ) -> npt.NDArray[np.float64]: - + return self.multi_start_instantiate(circuit, target, num_starts) def multi_start_instantiate( @@ -133,7 +123,7 @@ def multi_start_instantiate( num_starts: int, ) -> npt.NDArray[np.float64]: if len(circuit) == 0: - return [] + return np.array([]) circuit = circuit.copy() @@ -145,8 +135,10 @@ def multi_start_instantiate( """Instantiate `circuit`, see Instantiater for more info.""" target = UnitaryMatrixJax(self.check_target(target)) - locations = tuple([op.location for op in circuit]) - gates = tuple([op.gate for op in circuit]) + locations: tuple[CircuitLocation, ...] = tuple( + [op.location for op in circuit], + ) + gates: tuple[Gate, ...] = tuple([op.gate for op in circuit]) biggest_gate_size = max(gate.num_qudits for gate in gates) untrys = [] @@ -175,9 +167,10 @@ def multi_start_instantiate( res_var = _sweep2_jited( target, locations, gates, untrys, self.reset_iter, self.dist_tol, self.diff_tol_a, self.diff_tol_r, self.plateau_windows_size, - self.max_iters, self.min_iters, num_starts, self.diff_tol_step_r, self.diff_tol_step, self.beta + self.max_iters, self.min_iters, num_starts, self.diff_tol_step_r, + self.diff_tol_step, self.beta, ) - + it = res_var['iteration_counts'][0] c1s = res_var['c1s'] untrys = res_var['untrys'] @@ -195,7 +188,7 @@ def multi_start_instantiate( ) _logger.debug( - f'Terminated: {it} c1 = {c1s} Reached plateuo.\n' + f'Terminated: {it} c1 = {c1s} Reached plateau.\n' f'Best start is {best_start}', ) elif all(res_var['curr_step_calc_l']): @@ -204,43 +197,43 @@ def multi_start_instantiate( ' <= diff_tol_step_r * |prev_step_c1|.', ) _logger.debug( - f'Terminated: {it} c1 = {c1s} Reached plateuo.\n' + f'Terminated: {it} c1 = {c1s} Reached plateau.\n' f'Best start is {best_start}', ) elif it >= self.max_iters: _logger.debug('Terminated: iteration limit reached.') - + else: _logger.error( - f'Terminated with no good reason after {it} iterstion ' + f'Terminated with no good reason after {it} iteration ' f'with c1s {c1s}.', ) - params = [] + params: list[Array] = [] for untry, gate in zip(untrys[best_start], gates): - if isinstance(gate, ConstantGate): + if isinstance(gate, ConstantGate): params.extend([]) - else: + else: params.extend( gate.get_params( - _remove_padding_and_create_matrix(untry, gate), + _remove_padding_and_create_matrix(untry, gate), ), - ) - + ) + return np.array(params) - + @staticmethod def get_method_name() -> str: """Return the name of this method.""" return 'qfactor_jax_batched_jit' @staticmethod - def can_internaly_perform_multistart() -> bool: - """Probes if the instantiater can internaly perform multistrat.""" + def can_internally_perform_multistart() -> bool: + """Probes if the instantiater can internally perform multistart.""" return True @staticmethod - def is_capable(circuit) -> bool: + def is_capable(circuit: Circuit) -> bool: """Return true if the circuit can be instantiated.""" return all( isinstance( @@ -253,7 +246,7 @@ def is_capable(circuit) -> bool: ) @staticmethod - def get_violation_report(circuit) -> str: + def get_violation_report(circuit: Circuit) -> str: """ Return a message explaining why `circuit` cannot be instantiated. @@ -288,13 +281,13 @@ def get_violation_report(circuit) -> str: ) -def _initilize_circuit_tensor( - target_num_qudits, - target_radixes, - locations, - target_mat, - untrys, -): +def _initialize_circuit_tensor( + target_num_qudits: int, + target_radixes: Sequence[int], + locations: Sequence[CircuitLocation], + target_mat: Array, + untrys: list[Array], +) -> UnitaryBuilderJax: target_untry_builder = UnitaryBuilderJax( target_num_qudits, target_radixes, target_mat.conj().T, @@ -309,9 +302,10 @@ def _initilize_circuit_tensor( def _single_sweep( - locations, gates, amount_of_gates, target_untry_builder:UnitaryBuilderJax, - untrys, beta=0 -): + locations: tuple[CircuitLocation, ...], gates: tuple[Gate, ...], + amount_of_gates: int, target_untry_builder: UnitaryBuilderJax, + untrys: list[Array], beta: float = 0.0, +) -> tuple[UnitaryBuilderJax, Array]: # from right to left for k in reversed(range(amount_of_gates)): gate = gates[k] @@ -326,7 +320,10 @@ def _single_sweep( # Update current gate if gate.num_params > 0: env = target_untry_builder.calc_env_matrix(location) - untry = gate.optimize(env, get_untry=True, prev_utry=untry, beta=beta) + untry = gate.optimize( + env, get_untry=True, prev_untry=untry, + beta=beta, + ) untrys[k] = untry # Add updated gate to left of circuit tensor @@ -348,7 +345,7 @@ def _single_sweep( # Update current gate if gate.num_params > 0: env = target_untry_builder.calc_env_matrix(location) - untry = gate.optimize(env, get_untry=True, prev_utry=untry, beta=beta) + untry = gate.optimize(env, True, beta, untry) untrys[k] = untry # Add updated gate to right of circuit tensor @@ -359,12 +356,12 @@ def _single_sweep( return target_untry_builder, untrys - def _single_sweep_sim( - locations, gates, amount_of_gates, target_untry_builder, - untrys, beta=0 -): - + locations: tuple[CircuitLocation, ...], gates: tuple[Gate, ...], + amount_of_gates: int, target_untry_builder: UnitaryBuilderJax, + untrys: list[Array], beta: float = 0.0, +) -> list[Array]: + new_untrys = [] # from right to left for k in reversed(range(amount_of_gates)): @@ -380,11 +377,10 @@ def _single_sweep_sim( # Update current gate if gate.num_params > 0: env = target_untry_builder.calc_env_matrix(location) - new_untrys.append(gate.optimize(env, get_untry=True, prev_utry=untry, beta=beta)) + new_untrys.append(gate.optimize(env, True, beta, untry)) else: new_untrys.append(untry) - target_untry_builder.apply_left( untry, location, check_arguments=False, ) @@ -392,8 +388,9 @@ def _single_sweep_sim( return new_untrys[::-1] - -def _apply_padding_and_flatten(untry, gate, max_gate_size): +def _apply_padding_and_flatten( + untry: Array, gate: Gate, max_gate_size: int, +) -> Array: zero_pad_size = (2**max_gate_size)**2 - (2**gate.num_qudits)**2 if zero_pad_size > 0: zero_pad = jnp.zeros(zero_pad_size) @@ -402,17 +399,20 @@ def _apply_padding_and_flatten(untry, gate, max_gate_size): return jnp.array(untry.flatten()) -def _remove_padding_and_create_matrix(untry, gate): +def _remove_padding_and_create_matrix( + untry: Array, gate: Gate, +) -> Array: len_of_matrix = 2**gate.num_qudits size_to_keep = len_of_matrix**2 return untry[:size_to_keep].reshape((len_of_matrix, len_of_matrix)) def Loop_vars( - untrys, c1s, plateau_windows, curr_plateau_calc_l, - curr_reached_required_tol_l, iteration_counts, - target_untry_builders, prev_step_c1s, curr_step_calc_l -): + untrys: list[Array], c1s: Array, plateau_windows: Array, + curr_plateau_calc_l: Array, curr_reached_required_tol_l: Array, + iteration_counts: Array, target_untry_builders: Array, prev_step_c1s: Array, + curr_step_calc_l: Array, +) -> dict[str, Array]: d = {} d['untrys'] = untrys d['c1s'] = c1s @@ -428,10 +428,12 @@ def Loop_vars( def _sweep2( - target, locations, gates, untrys, n, dist_tol, diff_tol_a, - diff_tol_r, plateau_windows_size, max_iters, min_iters, - amount_of_starts, diff_tol_step_r, diff_tol_step, beta -): + target: UnitaryMatrixJax, locations: tuple[CircuitLocation, ...], + gates: tuple[Gate, ...], untrys: Array, n: int, dist_tol: float, + diff_tol_a: float, diff_tol_r: float, plateau_windows_size: int, + max_iters: int, min_iters: int, amount_of_starts: int, + diff_tol_step_r: float, diff_tol_step: int, beta: float, +) -> dict[str, Array]: c1s = jnp.array([1.0] * amount_of_starts) plateau_windows = jnp.array( [[0] * plateau_windows_size for @@ -440,7 +442,7 @@ def _sweep2( prev_step_c1s = jnp.array([1.0] * amount_of_starts) - def should_continue(var): + def should_continue(var: dict[str, Array]) -> bool: return jnp.logical_not( jnp.logical_or( jnp.any(var['curr_reached_required_tol_l']), @@ -450,57 +452,89 @@ def should_continue(var): var['iteration_counts'][0] > min_iters, jnp.logical_or( jnp.all(var['curr_plateau_calc_l']), - jnp.all(var['curr_step_calc_l']) - ) + jnp.all(var['curr_step_calc_l']), + ), ), ), ), ) def _while_body_to_be_vmaped( - untrys, c1, plateau_window, curr_plateau_calc, - curr_reached_required_tol, iteration_count, - target_untry_builder_tensor, prev_step_c1, curr_step_calc - ): + untrys: Array, c1: float, plateau_window: Array, + curr_plateau_calc: bool, curr_reached_required_tol: bool, + iteration_count: int, target_untry_builder_tensor: Array, + prev_step_c1: float, curr_step_calc: float, + ) -> tuple[Array, float, Array, bool, bool, int, Array, float, float]: amount_of_gates = len(gates) amount_of_qudits = target.num_qudits target_radixes = target.radixes - untrys_as_matrixs = [] + untrys_as_matrixes = [] for gate_index, gate in enumerate(gates): - untrys_as_matrixs.append( + untrys_as_matrixes.append( UnitaryMatrixJax( _remove_padding_and_create_matrix( untrys[gate_index], gate, ), gate.radixes, ), ) - untrys = untrys_as_matrixs - - # initilize every "n" iterations of the loop - operand_for_if = (untrys, target_untry_builder_tensor) - initilize_body = lambda x: _initilize_circuit_tensor( - amount_of_qudits, target_radixes, locations, target.numpy, x[0], - ).tensor - no_initilize_body = lambda x: x[1] - - target_untry_builder_tensor = jax.lax.cond( - iteration_count % n == 0, initilize_body, - no_initilize_body, operand_for_if, - ) + untrys = untrys_as_matrixes - target_untry_builder = UnitaryBuilderJax( - amount_of_qudits, target_radixes, - tensor=target_untry_builder_tensor, - ) + if 'All_ENVS' in os.environ: + target_untry_builder_tensor = _initialize_circuit_tensor( + amount_of_qudits, target_radixes, locations, + target.numpy, untrys, + ).tensor - iteration_count = iteration_count + 1 + target_untry_builder = UnitaryBuilderJax( + amount_of_qudits, target_radixes, + tensor=target_untry_builder_tensor, + ) + + iteration_count = iteration_count + 1 + + untrys = _single_sweep_sim( + locations, gates, amount_of_gates, target_untry_builder, + untrys, beta, + ) + + target_untry_builder_tensor = _initialize_circuit_tensor( + amount_of_qudits, target_radixes, locations, target.numpy, + untrys, + ).tensor + + target_untry_builder = UnitaryBuilderJax( + amount_of_qudits, target_radixes, + tensor=target_untry_builder_tensor, + ) + else: + + # initialize every "n" iterations of the loop + operand_for_if_init = (untrys, target_untry_builder_tensor) + initialize_body = lambda x: _initialize_circuit_tensor( + amount_of_qudits, target_radixes, locations, + target.numpy, x[0], + ).tensor + no_initialize_body = lambda x: x[1] + + target_untry_builder_tensor = jax.lax.cond( + iteration_count % n == 0, initialize_body, + no_initialize_body, operand_for_if_init, + ) + + target_untry_builder = UnitaryBuilderJax( + amount_of_qudits, target_radixes, + tensor=target_untry_builder_tensor, + ) + + iteration_count = iteration_count + 1 + + target_untry_builder, untrys = _single_sweep( + locations, gates, amount_of_gates, target_untry_builder, + untrys, beta, + ) - target_untry_builder, untrys = _single_sweep( - locations, gates, amount_of_gates, target_untry_builder, untrys, beta - ) - c2 = c1 dim = target_untry_builder.dim untry_res = target_untry_builder.tensor.reshape((dim, dim)) @@ -518,14 +552,17 @@ def _while_body_to_be_vmaped( ) curr_reached_required_tol = c1 < dist_tol - ##### Checking the plateau in a step - operand_for_if = (c1, prev_step_c1, curr_step_calc) - reached_step_body = lambda x: (jnp.abs(x[0]), (x[1] - jnp.abs(x[0])) < diff_tol_step_r * x[1]) + # Checking the plateau in a step + operand_for_if_plateau = (c1, prev_step_c1, curr_step_calc) + reached_step_body = lambda x: ( + jnp.abs(x[0]), (x[1] - jnp.abs(x[0])) < diff_tol_step_r * x[1], + ) not_reached_step_body = lambda x: (x[1], x[2]) prev_step_c1, curr_step_calc = jax.lax.cond( - (iteration_count+1) % diff_tol_step == 0, - reached_step_body, not_reached_step_body, operand_for_if) + (iteration_count + 1) % diff_tol_step == 0, + reached_step_body, not_reached_step_body, operand_for_if_plateau, + ) biggest_gate_size = max(gate.num_qudits for gate in gates) final_untrys_padded = jnp.array([ @@ -538,12 +575,12 @@ def _while_body_to_be_vmaped( return ( final_untrys_padded, c1, plateau_window, curr_plateau_calc, curr_reached_required_tol, iteration_count, - target_untry_builder.tensor, prev_step_c1, curr_step_calc + target_untry_builder.tensor, prev_step_c1, curr_step_calc, ) while_body_vmaped = jax.vmap(_while_body_to_be_vmaped) - def while_body(var): + def while_body(var: dict[str, Array]) -> dict[str, Array]: return Loop_vars( *while_body_vmaped( var['untrys'], var['c1s'], @@ -553,7 +590,7 @@ def while_body(var): var['iteration_counts'], var['target_untry_builders'], var['prev_step_c1s'], - var['curr_step_calc_l'] + var['curr_step_calc_l'], ), ) @@ -569,21 +606,22 @@ def while_body(var): jnp.array([False] * amount_of_starts), jnp.array([0] * amount_of_starts), initial_untray_builders_values, prev_step_c1s, - jnp.array([False] * amount_of_starts) + jnp.array([False] * amount_of_starts), ) - if 'PRINT_LOSS_QFACTOR' in os.environ: loop_var = initial_loop_var i = 1 - while(should_continue(loop_var)): + while should_continue(loop_var): loop_var = while_body(loop_var) - print("LOSS:",i , loop_var['c1s']) - i +=1 + print('LOSS:', i, loop_var['c1s']) + i += 1 res_var = loop_var else: - res_var = jax.lax.while_loop(should_continue, while_body, initial_loop_var) + res_var = jax.lax.while_loop( + should_continue, while_body, initial_loop_var, + ) return res_var @@ -593,100 +631,6 @@ def while_body(var): else: _sweep2_jited = jax.jit( _sweep2, static_argnums=( - 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ), - ) - - - - - - - -# %% -import numpy as np -from bqskit.ir.circuit import Circuit -from bqskit.ir.gates import VariableUnitaryGate -from bqskit.qis.unitary import UnitaryMatrix - -toffoli = np.array([ - [1, 0, 0, 0, 0, 0, 0, 0], - [0, 1, 0, 0, 0, 0, 0, 0], - [0, 0, 1, 0, 0, 0, 0, 0], - [0, 0, 0, 1, 0, 0, 0, 0], - [0, 0, 0, 0, 1, 0, 0, 0], - [0, 0, 0, 0, 0, 1, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 1], - [0, 0, 0, 0, 0, 0, 1, 0], - ]) -target = UnitaryMatrixJax(toffoli) -circuit = Circuit(3) -circuit.append_gate(VariableUnitaryGate(2), [1, 2]) -circuit.append_gate(VariableUnitaryGate(2), [0, 2]) -circuit.append_gate(VariableUnitaryGate(2), [1, 2]) -circuit.append_gate(VariableUnitaryGate(2), [0, 2]) -circuit.append_gate(VariableUnitaryGate(2), [0, 1]) - - - -if True: - - circuit = Circuit(2) - if False: - circuit.append_gate(VariableUnitaryGate(2), [0,1]) - else: - circuit.append_gate(VariableUnitaryGate(1), [0]) - circuit.append_gate(VariableUnitaryGate(1), [1]) - circuit.append_gate(CXGate(), [0, 1]) - circuit.append_gate(VariableUnitaryGate(1), [0]) - circuit.append_gate(VariableUnitaryGate(1), [1]) - circuit.append_gate(CXGate(), [0, 1]) - circuit.append_gate(VariableUnitaryGate(1), [0]) - circuit.append_gate(VariableUnitaryGate(1), [1]) - circuit.append_gate(CXGate(), [0, 1]) - circuit.append_gate(VariableUnitaryGate(1), [0]) - circuit.append_gate(VariableUnitaryGate(1), [1]) - - target = UnitaryMatrixJax(unitary_group.rvs(4)) - -locations = tuple([op.location for op in circuit]) -for op in circuit: - g = op.gate - if isinstance(g, VariableUnitaryGate): - g.__class__ = VariableUnitaryGateAcc -gates = tuple([op.gate for op in circuit]) -pre_padding_untrys = [] -for gate in gates: - size_of_untry = 2**gate.num_qudits - - if isinstance(gate, VariableUnitaryGateAcc): - pre_padding_untrys.extend([ - UnitaryMatrixJax(unitary_group.rvs(size_of_untry)) for - _ in range(1) - ]) - else: - pre_padding_untrys.extend( [ - UnitaryMatrixJax(gate.get_unitary().numpy) for - _ in range(1) - ]) - - -# %% -for op in circuit: - g = op.gate - if isinstance(g, VariableUnitaryGate): - g.__class__ = VariableUnitaryGateAcc -params = state_sample_sweep(4, target, locations, gates, pre_padding_untrys, num_qudits=2, radixes=(2,2), dist_tol=1e-10, beta=0) -# params = state_sample_sweep(10, target, locations, gates, pre_padding_untrys, num_qudits=3, radixes=(2,2,2), dist_tol=1e-9, beta=0) - -for op in circuit: - g = op.gate - if isinstance(g, VariableUnitaryGateAcc): - g.__class__ = VariableUnitaryGate -circuit.set_params(params) - -dist = circuit.get_unitary().get_distance_from(UnitaryMatrix(target.numpy), 1) -print(f'{dist = }') - - -# %% + ) \ No newline at end of file From 9307ffa4c692eb413bae9f63786ce2da0522c13d Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 2 Oct 2023 23:03:27 -0700 Subject: [PATCH 15/59] Fixing all pre-commit issues --- bqskitqfactorjax/qfactor_sample_jax.py | 58 +++++++++++++++++--------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index eec7184..be209d4 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -2,6 +2,7 @@ import logging import os +from typing import Sequence from typing import TYPE_CHECKING import jax @@ -130,6 +131,8 @@ def multi_start_instantiate( locations = tuple([op.location for op in circuit]) gates = tuple([op.gate for op in circuit]) biggest_gate_size = max(gate.num_qudits for gate in gates) + radixes = target.radixes + num_qudits = target.num_qudits untrys = [] @@ -162,17 +165,19 @@ def multi_start_instantiate( amount_of_trainng_states = np.round(amount_of_trainng_states) training_states_kets = self.generate_random_states( - amount_of_trainng_states, + amount_of_trainng_states, np.prod(radixes), ) validation_states_kets = self.generate_random_states( - self.amount_of_validation_states, + self.amount_of_validation_states, np.prod(radixes), ) - final_untrys, training_costs, validation_costs, iteration_counts = _jited_loop_vmaped_state_sample_sweep( - target, locations, gates, untrys, - self.dist_tol, self.max_iters, self.beta, - training_states_kets, validation_states_kets, - ) + final_untrys, training_costs, validation_costs, iteration_counts = \ + _jited_loop_vmaped_state_sample_sweep( + target, num_qudits, radixes, locations, gates, untrys, + self.dist_tol, self.max_iters, self.beta, + num_starts, self.min_iters, self.overtrian_ratio, + training_states_kets, validation_states_kets, + ) it = iteration_counts[0] untrys = final_untrys @@ -195,7 +200,7 @@ def multi_start_instantiate( f'with c1s {training_costs}.', ) - params = [] + params: list[Sequence[float]] = [] for untry, gate in zip(untrys[best_start], gates): if isinstance(gate, ConstantGate): params.extend([]) @@ -212,21 +217,23 @@ def multi_start_instantiate( def generate_random_states( amount_of_states: int, size_of_state: int, - ) -> list[npt.NDArray]: + ) -> list[npt.NDArray[np.complex128]]: """ Generate a list of random state vectors (kets) using random unitary matrices. - This function generates a specified number of random quantum state vectors - (kets) by creating random unitary matrices and extracting their first columns. + This function generates a specified number of random quantum state + vectors (kets) by creating random unitary matrices and extracting + their first columns. Args: amount_of_states (int): The number of random states to generate. size_of_state (int): The dimension of each state vector (ket). Returns: - list of ndarrays: A list containing random quantum state vectors (kets). - Each ket is represented as a numpy ndarray of shape (size_of_state, 1). + list of ndarrays: A list containing random quantum state vectors. + Each ket is represented as a numpy ndarray of + shape (size_of_state, 1). """ states_kets = [] states_to_add = amount_of_states @@ -286,7 +293,11 @@ def _loop_vmaped_state_sample_sweep( # the same type, and also the check should be a function that accepts it # and return a boolean - def should_continue(loop_var: tuple): + def should_continue( + loop_var: tuple[ + Array, Array[float], Array[float], Array[int], + ], + ) -> Array[bool]: _, training_costs, validation_costs, iteration_counts = loop_var any_reached_required_tol = jnp.any( @@ -320,7 +331,13 @@ def should_continue(loop_var: tuple): ), ) - def _while_body_to_be_vmaped(loop_var: tuple): + def _while_body_to_be_vmaped( + loop_var: tuple[ + Array, Array[float], Array[float], Array[int], + ], + ) -> tuple[ + Array, Array[float], Array[float], Array[int], + ]: untrys, training_cost, validation_cost, iteration_count = loop_var @@ -334,10 +351,11 @@ def _while_body_to_be_vmaped(loop_var: tuple): ), ) - untrys_as_matrixs, training_cost, validation_cost = state_sample_single_sweep( - locations, gates, untrys_as_matrixs, - beta, A_train, A_val, B0_train, B0_val, - ) + untrys_as_matrixs, training_cost, validation_cost =\ + state_sample_single_sweep( + locations, gates, untrys_as_matrixs, + beta, A_train, A_val, B0_train, B0_val, + ) iteration_count += 1 @@ -375,7 +393,7 @@ def state_sample_single_sweep( untrys: list[UnitaryMatrixJax], beta: float, A_train: RHSTensor, A_val: RHSTensor, B0_train: LHSTensor, B0_val: LHSTensor, -) -> list[UnitaryMatrixJax] | float | float: +) -> tuple[list[UnitaryMatrixJax], float, float]: amount_of_gates = len(gates) B = [B0_train] From 232c1398042ce40e6b033ab35cd449b63a87caf8 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 2 Oct 2023 23:59:00 -0700 Subject: [PATCH 16/59] Fixing pre-commit issues --- bqskitqfactorjax/__init__.py | 7 +- bqskitqfactorjax/qfactor_jax.py | 2 +- bqskitqfactorjax/qfactor_sample_jax.py | 30 +++--- bqskitqfactorjax/singlelegedtensor.py | 123 ++++++++++++++----------- 4 files changed, 90 insertions(+), 72 deletions(-) diff --git a/bqskitqfactorjax/__init__.py b/bqskitqfactorjax/__init__.py index 81e5511..0df6bdf 100644 --- a/bqskitqfactorjax/__init__.py +++ b/bqskitqfactorjax/__init__.py @@ -1,4 +1,9 @@ from __future__ import annotations __all__ = [ - 'qfactor_jax', 'unitary_acc', 'unitarybuilderjax', 'unitarymatrixjax', + 'qfactor_jax', + 'qfactor_sample_jax', + 'unitary_acc', + 'unitarybuilderjax', + 'unitarymatrixjax', + 'singlelegedtensor', ] diff --git a/bqskitqfactorjax/qfactor_jax.py b/bqskitqfactorjax/qfactor_jax.py index c3d84e0..db7a508 100644 --- a/bqskitqfactorjax/qfactor_jax.py +++ b/bqskitqfactorjax/qfactor_jax.py @@ -633,4 +633,4 @@ def while_body(var: dict[str, Array]) -> dict[str, Array]: _sweep2, static_argnums=( 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ), - ) \ No newline at end of file + ) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index be209d4..d73b70d 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -7,9 +7,6 @@ import jax import jax.numpy as jnp -import jax.numpy.logical_and as jand -import jax.numpy.logical_not as jnot -import jax.numpy.logical_or as jor import numpy as np import numpy.typing as npt from bqskit.ir import CircuitLocation @@ -21,15 +18,18 @@ from bqskit.qis.state import StateSystem from bqskit.qis.state import StateVector from jax import Array +from jax.numpy import logical_and as jand +from jax.numpy import logical_not as jnot +from jax.numpy import logical_or as jor from scipy.stats import unitary_group -from bqskitgpu.qfactor_jax import _apply_padding_and_flatten -from bqskitgpu.qfactor_jax import _remove_padding_and_create_matrix -from bqskitgpu.singlelegedtensor import LHSTensor -from bqskitgpu.singlelegedtensor import RHSTensor -from bqskitgpu.singlelegedtensor import SingleLegSideTensor -from bqskitgpu.unitary_acc import VariableUnitaryGateAcc -from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +from bqskitqfactorjax.qfactor_jax import _apply_padding_and_flatten +from bqskitqfactorjax.qfactor_jax import _remove_padding_and_create_matrix +from bqskitqfactorjax.singlelegedtensor import LHSTensor +from bqskitqfactorjax.singlelegedtensor import RHSTensor +from bqskitqfactorjax.singlelegedtensor import SingleLegSideTensor +from bqskitqfactorjax.unitary_acc import VariableUnitaryGateAcc +from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax if TYPE_CHECKING: from bqskit.ir.circuit import Circuit @@ -165,10 +165,10 @@ def multi_start_instantiate( amount_of_trainng_states = np.round(amount_of_trainng_states) training_states_kets = self.generate_random_states( - amount_of_trainng_states, np.prod(radixes), + amount_of_trainng_states, int(np.prod(radixes)), ) validation_states_kets = self.generate_random_states( - self.amount_of_validation_states, np.prod(radixes), + self.amount_of_validation_states, int(np.prod(radixes)), ) final_untrys, training_costs, validation_costs, iteration_counts = \ @@ -413,7 +413,7 @@ def state_sample_single_sweep( ) # iterate over every gate from right to left and update it - new_untrys = [None] * amount_of_gates + new_untrys_rev: list[UnitaryMatrixJax] = [] a_train: RHSTensor = A_train.copy() a_val: RHSTensor = A_val.copy() for idx in reversed(range(amount_of_gates)): @@ -428,11 +428,11 @@ def state_sample_single_sweep( prev_utry=utry, beta=beta, ) - new_untrys[idx] = utry + new_untrys_rev.append(utry) a_train.apply_left(utry, location) a_val.apply_left(utry, location) - untrys = new_untrys + untrys = new_untrys_rev[::-1] training_cost = calc_cost(A_train, B0_train, a_train) diff --git a/bqskitqfactorjax/singlelegedtensor.py b/bqskitqfactorjax/singlelegedtensor.py index 93aca96..1cf7cda 100644 --- a/bqskitqfactorjax/singlelegedtensor.py +++ b/bqskitqfactorjax/singlelegedtensor.py @@ -1,66 +1,90 @@ from __future__ import annotations +from typing import Sequence +from typing import TypeVar + import jax.numpy as jnp +from bqskit.ir import CircuitLocation +from jax import Array -from bqskit.qis.unitary import UnitaryMatrix +from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax -from typing import Sequence -from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +T = TypeVar('T', bound='SingleLegSideTensor') class SingleLegSideTensor(): """ - The class represents a tensor that has only a single leg in one of his sides. + The class represents a tensor that has only a single leg in one of his + sides. + The single leg will always be index 0 """ - def __init__(self, num_qudits: int, radixes: Sequence[int] = [], list_of_states:Sequence=[], tensor=None, single_leg_radix=None) -> None: - + def __init__( + self, num_qudits: int, radixes: Sequence[int] = [], + list_of_states: Array = jnp.array([]), + tensor: Array | None = None, single_leg_radix: int | None = None, + ) -> None: + if len(list_of_states) > 0: first_state = list_of_states[0] - - assert any(d==1 for d in first_state.shape ) - assert all(s.shape==first_state.shape for s in list_of_states) + + assert any(d == 1 for d in first_state.shape) + assert all(s.shape == first_state.shape for s in list_of_states) self.num_qudits = num_qudits self.num_of_legs = num_qudits + 1 - self.radixes = tuple(radixes if len(radixes) > 0 else [2] * num_qudits) + self.radixes = tuple( + radixes if len(radixes) > 0 else [2] * num_qudits, + ) self.single_leg_radix = len(list_of_states) - self.tensor = jnp.array(list_of_states).reshape(self.single_leg_radix, *self.radixes) - elif tensor != None: + self.tensor = jnp.array(list_of_states).reshape( + self.single_leg_radix, *self.radixes, + ) + elif tensor is not None and single_leg_radix is not None: self.tensor = tensor self.single_leg_radix = single_leg_radix self.num_qudits = num_qudits self.num_of_legs = num_qudits + 1 - self.radixes = tuple(radixes if len(radixes) > 0 else [2] * num_qudits) + self.radixes = tuple( + radixes if len(radixes) > 0 else [2] * num_qudits, + ) else: - raise "can't create the instance" - - def copy(self)->SingleLegSideTensor: - return self.__class__(tensor=self.tensor.copy(), num_qudits = self.num_qudits,radixes = self.radixes, single_leg_radix = self.single_leg_radix) + raise RuntimeError("can't create the instance") + + def copy(self: T) -> T: + return self.__class__( + tensor=self.tensor.copy(), + num_qudits=self.num_qudits, + radixes=self.radixes, + single_leg_radix=self.single_leg_radix, + ) @staticmethod - def calc_env(left:LHSTensor, right:RHSTensor, indexes_to_leave_open:Sequence[int]): - - #verify correct shape + def calc_env( + left: LHSTensor, right: RHSTensor, + indexes_to_leave_open: Sequence[int], + ) -> Array: + + # verify correct shape assert left.radixes == right.radixes - assert left.single_leg_radix == right.single_leg_radix, f'{left.single_leg_radix} != {right.single_leg_radix}' + assert left.single_leg_radix == right.single_leg_radix, \ + f'{left.single_leg_radix} != {right.single_leg_radix}' - - left_contraction_indexs = list(range(left.num_qudits+1)) - right_contraction_indexs = list(range(left.num_qudits+1)) + left_contraction_indexs = list(range(left.num_qudits + 1)) + right_contraction_indexs = list(range(left.num_qudits + 1)) size_of_open = len(indexes_to_leave_open) for leg_num, i in enumerate(indexes_to_leave_open): - left_contraction_indexs[i+1] = size_of_open+leg_num+left.num_of_legs - right_contraction_indexs[i+1] = leg_num+left.num_of_legs + left_contraction_indexs[i + 1] = size_of_open + \ + leg_num + left.num_of_legs + right_contraction_indexs[i + 1] = leg_num + left.num_of_legs - env_tensor = jnp.einsum( left.tensor, left_contraction_indexs, - right.tensor, right_contraction_indexs + right.tensor, right_contraction_indexs, ) env_mat = env_tensor.reshape((2**size_of_open, -1)) @@ -72,10 +96,8 @@ class RHSTensor(SingleLegSideTensor): def apply_left( self, utry: UnitaryMatrixJax, - location: tuple, - ) -> None: - - + location: Sequence[CircuitLocation], + ) -> None: """ Apply the specified unitary on the left of this rhs tensor @@ -89,18 +111,19 @@ def apply_left( n ------------| | '-----' - """ + """ utry_tensor = utry.get_tensor_format() utry_size = len(utry.radixes) + utry_tensor_indexs = [ + i + self.num_of_legs for i in range(utry_size) + ] + [1 + l for l in location] - utry_tensor_indexs = [i+self.num_of_legs for i in range(utry_size)] + [1+l for l in location] - rhs_tensor_indexes = list(range(self.num_of_legs)) output_tensor_index = list(range(self.num_of_legs)) - #matching the leg indexs of the utry + # matching the leg indexs of the utry for i, loc in enumerate(location): rhs_tensor_indexes[1 + loc] = i + self.num_of_legs @@ -115,37 +138,27 @@ class LHSTensor(SingleLegSideTensor): def apply_right( self, utry: UnitaryMatrixJax, - location: tuple, - ) -> None: - - + location: Sequence[CircuitLocation], + ) -> None: """ Apply the specified unitary on the right of this lhs tensor. - The reuslt looks like this - .-----. .------. - | |---| |- 1 - | |---| utry |- 2 - . . '------' - 0-| . - . . - . . - | |------------ n - '-----' + The reuslt looks like this .-----. .------. | |---| + |- 1 | |---| utry |- 2 . . '------' 0-| + . . . . . | |------------ n '-----' """ - + utry_tensor = utry.get_tensor_format() utry_size = len(utry.radixes) - - utry_tensor_indexs = [1+l for l in location] + [i+self.num_of_legs for i in range(utry_size)] + utry_tensor_indexs = [1 + l for l in location] + \ + [i + self.num_of_legs for i in range(utry_size)] lhs_tensor_indexes = list(range(self.num_of_legs)) output_tensor_index = list(range(self.num_of_legs)) - #matching the leg indexs of the utry + # matching the leg indexs of the utry for i, loc in enumerate(location): lhs_tensor_indexes[1 + loc] = i + self.num_of_legs - self.tensor = jnp.einsum( utry_tensor, utry_tensor_indexs, From 3c44d6fea509916b1aff358176c9f4e5735cb957 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 2 Oct 2023 23:59:42 -0700 Subject: [PATCH 17/59] Adding the example for the sampling case --- .../toffoli_instantiation_using_sampling.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 examples/toffoli_instantiation_using_sampling.py diff --git a/examples/toffoli_instantiation_using_sampling.py b/examples/toffoli_instantiation_using_sampling.py new file mode 100644 index 0000000..431efc7 --- /dev/null +++ b/examples/toffoli_instantiation_using_sampling.py @@ -0,0 +1,69 @@ +""" +Numerical Instantiation is the foundation of many of BQSKit's algorithms. + +This is the same instantiation example as in BQSKit using the GPU implementation +of QFactor +""" +from __future__ import annotations + +import numpy as np +from bqskit.ir.circuit import Circuit +from bqskit.ir.gates import VariableUnitaryGate +from bqskit.qis.unitary import UnitaryMatrix + +from bqskitqfactorjax.qfactor_sample_jax import QFactor_sample_jax + + +def run_toffoli_instantiation(dist_tol_requested: float = 1e-10) -> float: + qfactr_gpu_instantiator = QFactor_sample_jax( + + dist_tol=dist_tol_requested, # Stopping criteria for distance + + max_iters=100000, # Maximum number of iterations + min_iters=10, # Minimum number of iterations + + # Regularization parameter - [0.0 - 1.0] + # Increase to overcome local minima at the price of longer compute + beta=0.0, + + amount_of_validation_states=2, + num_params_coeff=1, + overtrain_ratio=1 / 32, + ) + + # We will optimize towards the Toffoli unitary. + toffoli = np.array([ + [1, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 1], + [0, 0, 0, 0, 0, 0, 1, 0], + ]) + toffoli = UnitaryMatrix(toffoli) + + # Start with the circuit structure + circuit = Circuit(3) + circuit.append_gate(VariableUnitaryGate(2), [1, 2]) + circuit.append_gate(VariableUnitaryGate(2), [0, 2]) + circuit.append_gate(VariableUnitaryGate(2), [1, 2]) + circuit.append_gate(VariableUnitaryGate(2), [0, 2]) + circuit.append_gate(VariableUnitaryGate(2), [0, 1]) + + # Instantiate the circuit template with QFactor + circuit.instantiate( + toffoli, + multistarts=16, + method=qfactr_gpu_instantiator, + ) + + # Calculate and print final distance + dist = circuit.get_unitary().get_distance_from(toffoli, 1) + return dist + + +if __name__ == '__main__': + dist = run_toffoli_instantiation() + print('Final Distance: ', dist) From c97e967709829396a38b2c1d6ae4e163037d842e Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 3 Oct 2023 00:27:13 -0700 Subject: [PATCH 18/59] Fixing some typos, and adding missing methods --- bqskitqfactorjax/qfactor_sample_jax.py | 104 +++++++++++++++++++------ 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index d73b70d..8e38706 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -12,6 +12,7 @@ from bqskit.ir import CircuitLocation from bqskit.ir import Gate from bqskit.ir.gates import ConstantGate +from bqskit.ir.gates import U3Gate from bqskit.ir.gates import VariableUnitaryGate from bqskit.ir.opt import Instantiater from bqskit.qis import UnitaryMatrix @@ -175,7 +176,7 @@ def multi_start_instantiate( _jited_loop_vmaped_state_sample_sweep( target, num_qudits, radixes, locations, gates, untrys, self.dist_tol, self.max_iters, self.beta, - num_starts, self.min_iters, self.overtrian_ratio, + num_starts, self.min_iters, self.overtrain_ratio, training_states_kets, validation_states_kets, ) @@ -213,6 +214,65 @@ def multi_start_instantiate( return np.array(params) + @staticmethod + def get_method_name() -> str: + """Return the name of this method.""" + return 'qfactor_jax_batched_jit' + + @staticmethod + def can_internally_perform_multistart() -> bool: + """Probes if the instantiater can internally perform multistart.""" + return True + + @staticmethod + def is_capable(circuit: Circuit) -> bool: + """Return true if the circuit can be instantiated.""" + return all( + isinstance( + gate, ( + VariableUnitaryGate, + VariableUnitaryGateAcc, U3Gate, ConstantGate, + ), + ) + for gate in circuit.gate_set + ) + + @staticmethod + def get_violation_report(circuit: Circuit) -> str: + """ + Return a message explaining why `circuit` cannot be instantiated. + + Args: + circuit (Circuit): Generate a report for this circuit. + + Raises: + ValueError: If `circuit` can be instantiated with this + instantiater. + """ + + invalid_gates = { + gate + for gate in circuit.gate_set + if not isinstance( + gate, ( + VariableUnitaryGate, + VariableUnitaryGateAcc, + U3Gate, + ConstantGate, + ), + ) + } + + if len(invalid_gates) == 0: + raise ValueError('Circuit can be instantiated.') + + return ( + 'Cannot instantiate circuit with qfactor because' + ' the following gates are not locally optimizable with jax: %s.' + % ', '.join(str(g) for g in invalid_gates) + ) + + @staticmethod def generate_random_states( amount_of_states: int, @@ -260,11 +320,11 @@ def _loop_vmaped_state_sample_sweep( validation_states_bras = jax.vmap( lambda ket: ket.T.conj(), - )(validation_states_kets) + )(jnp.array(validation_states_kets)) training_states_bras = jax.vmap( lambda ket: ket.T.conj(), - )(training_states_kets) + )(jnp.array(training_states_kets)) # Calculate the A and B0 tensor target_dagger = target.T.conj() @@ -301,35 +361,31 @@ def should_continue( _, training_costs, validation_costs, iteration_counts = loop_var any_reached_required_tol = jnp.any( - jax.vmap( - lambda cost: cost <= dist_tol, - training_costs, - ), - ) + jax.vmap( + lambda cost: cost <= dist_tol + )(training_costs) + ) + reached_max_iteration = iteration_counts[0] > max_iters - above_min_iteration = iteration_counts[0] > min_iters any_reached_over_training = jnp.any( - jax.vmap( - lambda train_cost, val_cost: - val_cost > overtrian_ratio * train_cost, - (training_costs, validation_costs), - ), - ) + jax.vmap( + lambda train_cost, val_cost: + val_cost > overtrian_ratio * train_cost,) + (training_costs, validation_costs) + ), return jnot( - jor( - any_reached_required_tol, jor( - reached_max_iteration, - jand( - above_min_iteration, - any_reached_over_training, + any_reached_required_tol, + jor( + reached_max_iteration, + # jand(above_min_iteration, any_reached_over_training), + any_reached_over_training + ), ), - ), - ), - ) + ) def _while_body_to_be_vmaped( loop_var: tuple[ From c62c9794e90162c87925c3901569cfb5163d5068 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 3 Oct 2023 00:31:01 -0700 Subject: [PATCH 19/59] pre=commit fixes --- bqskitqfactorjax/qfactor_sample_jax.py | 47 +++++++++++++------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 8e38706..dac5c39 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -19,9 +19,6 @@ from bqskit.qis.state import StateSystem from bqskit.qis.state import StateVector from jax import Array -from jax.numpy import logical_and as jand -from jax.numpy import logical_not as jnot -from jax.numpy import logical_or as jor from scipy.stats import unitary_group from bqskitqfactorjax.qfactor_jax import _apply_padding_and_flatten @@ -272,7 +269,6 @@ def get_violation_report(circuit: Circuit) -> str: % ', '.join(str(g) for g in invalid_gates) ) - @staticmethod def generate_random_states( amount_of_states: int, @@ -361,31 +357,34 @@ def should_continue( _, training_costs, validation_costs, iteration_counts = loop_var any_reached_required_tol = jnp.any( - jax.vmap( - lambda cost: cost <= dist_tol - )(training_costs) - ) - + jax.vmap( + lambda cost: cost <= dist_tol, + )(training_costs), + ) + reached_max_iteration = iteration_counts[0] > max_iters above_min_iteration = iteration_counts[0] > min_iters any_reached_over_training = jnp.any( - jax.vmap( - lambda train_cost, val_cost: - val_cost > overtrian_ratio * train_cost,) - (training_costs, validation_costs) - ), - - return jnot( - jor( - any_reached_required_tol, - jor( - reached_max_iteration, - # jand(above_min_iteration, any_reached_over_training), - any_reached_over_training - ), + jax.vmap( + lambda train_cost, val_cost: + val_cost > overtrian_ratio * train_cost, + ) + (training_costs, validation_costs), + ), + + return jnp.logical_not( + jnp.logical_or( + any_reached_required_tol, + jnp.logical_or( + reached_max_iteration, + jnp.logical_and( + above_min_iteration, + any_reached_over_training, ), - ) + ), + ), + ) def _while_body_to_be_vmaped( loop_var: tuple[ From 0af6e8196d79cc3befbe98c26ddd9b4752c397d9 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 3 Oct 2023 00:54:02 -0700 Subject: [PATCH 20/59] Toffoli example now working --- bqskitqfactorjax/qfactor_sample_jax.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index dac5c39..9644c40 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -366,12 +366,7 @@ def should_continue( above_min_iteration = iteration_counts[0] > min_iters any_reached_over_training = jnp.any( - jax.vmap( - lambda train_cost, val_cost: - val_cost > overtrian_ratio * train_cost, - ) - (training_costs, validation_costs), - ), + training_costs < overtrian_ratio* validation_costs) return jnp.logical_not( jnp.logical_or( @@ -419,7 +414,7 @@ def _while_body_to_be_vmaped( _apply_padding_and_flatten( untry.numpy.flatten( ), gate, biggest_gate_size, - ) for untry, gate in zip(untrys, gates) + ) for untry, gate in zip(untrys_as_matrixs, gates) ]) return ( @@ -480,7 +475,7 @@ def state_sample_single_sweep( env = SingleLegSideTensor.calc_env(b, a_train, location) utry = gate.optimize( env.T, get_untry=True, - prev_utry=utry, beta=beta, + prev_untry=utry, beta=beta, ) new_untrys_rev.append(utry) @@ -497,11 +492,13 @@ def state_sample_single_sweep( def calc_cost(A: RHSTensor, B0: LHSTensor, a: RHSTensor) -> float: - return 2 * ( + cost = 2 * ( 1 - jnp.real( SingleLegSideTensor.calc_env(B0, a, [])[0], - ) / A.single_leg_radix - ) + ) / A.single_leg_radix + ) + + return jnp.squeeze(cost) if 'NO_JIT_QFACTOR' in os.environ: From 9a3fc4625f913f2c76a895e1902930f8fdec0c8b Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 3 Oct 2023 01:03:55 -0700 Subject: [PATCH 21/59] Fixing pre-commit --- bqskitqfactorjax/qfactor_sample_jax.py | 11 ++-- tests/test_single_leg_tensor.py | 78 +++++++++++++++++--------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 9644c40..983974b 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -366,7 +366,8 @@ def should_continue( above_min_iteration = iteration_counts[0] > min_iters any_reached_over_training = jnp.any( - training_costs < overtrian_ratio* validation_costs) + training_costs < overtrian_ratio * validation_costs, + ) return jnp.logical_not( jnp.logical_or( @@ -492,12 +493,12 @@ def state_sample_single_sweep( def calc_cost(A: RHSTensor, B0: LHSTensor, a: RHSTensor) -> float: - cost = 2 * ( + cost = 2 * ( 1 - jnp.real( SingleLegSideTensor.calc_env(B0, a, [])[0], - ) / A.single_leg_radix - ) - + ) / A.single_leg_radix + ) + return jnp.squeeze(cost) diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py index 4926880..23f9ffa 100644 --- a/tests/test_single_leg_tensor.py +++ b/tests/test_single_leg_tensor.py @@ -1,31 +1,44 @@ -#%% -import pytest -from random import randint, sample +from __future__ import annotations + +from random import randint +from random import sample + import jax.numpy as jnp +import pytest +from bqskit.ir.gates import CXGate +from bqskit.ir.gates import HGate +from bqskitgpu.singlelegedtensor import LHSTensor +from bqskitgpu.singlelegedtensor import RHSTensor +from bqskitgpu.singlelegedtensor import SingleLegSideTensor +from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax from scipy.stats import unitary_group -from bqskitgpu.singlelegedtensor import SingleLegSideTensor, RHSTensor, LHSTensor -from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax -from bqskit.ir.gates import HGate, CXGate -@pytest.mark.parametrize("num_qubits, N", [(randint(2, 7), randint(3,10)) for _ in range(6)]) -def test_full_contraction_with_complex_conj(num_qubits, N): - random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] +@pytest.mark.parametrize( + 'num_qubits, N', + [(randint(2, 7), randint(3, 10)) for _ in range(6)], +) +def test_full_contraction_with_complex_conj(num_qubits: int, N: int) -> None: + random_kets = [unitary_group.rvs(2**num_qubits)[:, :1] for _ in range(N)] random_bras = [ket.T.conj() for ket in random_kets] - rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) - lhs = LHSTensor(list_of_states = random_kets, num_qudits = num_qubits) + rhs = RHSTensor(list_of_states=random_bras, num_qudits=num_qubits) + lhs = LHSTensor(list_of_states=random_kets, num_qudits=num_qubits) res = SingleLegSideTensor.calc_env(lhs, rhs, []).reshape(1)[0] assert jnp.isclose(res, N) -@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) -def test_apply_left_H(num_qubits, N): - random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + +@pytest.mark.parametrize( + 'num_qubits, N', + [(randint(2, 7), randint(3, 10)) for _ in range(3)], +) +def test_apply_left_H(num_qubits: int, N: int) -> None: + random_kets = [unitary_group.rvs(2**num_qubits)[:, :1] for _ in range(N)] random_bras = [ket.T.conj() for ket in random_kets] - rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + rhs = RHSTensor(list_of_states=random_bras, num_qudits=num_qubits) orig = rhs.copy() H_mat = UnitaryMatrixJax(HGate().get_unitary()) @@ -35,12 +48,16 @@ def test_apply_left_H(num_qubits, N): rhs.apply_left(H_mat, location) assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) -@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) -def test_apply_right_H(num_qubits, N): - random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + +@pytest.mark.parametrize( + 'num_qubits, N', + [(randint(2, 7), randint(3, 10)) for _ in range(3)], +) +def test_apply_right_H(num_qubits: int, N: int) -> None: + random_kets = [unitary_group.rvs(2**num_qubits)[:, :1] for _ in range(N)] random_bras = [ket.T.conj() for ket in random_kets] - rhs = LHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + rhs = LHSTensor(list_of_states=random_bras, num_qudits=num_qubits) orig = rhs.copy() H_mat = UnitaryMatrixJax(HGate().get_unitary()) @@ -50,12 +67,16 @@ def test_apply_right_H(num_qubits, N): rhs.apply_right(H_mat, location) assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) -@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) -def test_apply_left_CX(num_qubits, N): - random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] + +@pytest.mark.parametrize( + 'num_qubits, N', + [(randint(2, 7), randint(3, 10)) for _ in range(3)], +) +def test_apply_left_CX(num_qubits: int, N: int) -> None: + random_kets = [unitary_group.rvs(2**num_qubits)[:, :1] for _ in range(N)] random_bras = [ket.T.conj() for ket in random_kets] - rhs = RHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + rhs = RHSTensor(list_of_states=random_bras, num_qudits=num_qubits) orig = rhs.copy() H_mat = UnitaryMatrixJax(CXGate().get_unitary()) @@ -66,12 +87,15 @@ def test_apply_left_CX(num_qubits, N): assert all(jnp.isclose(rhs.tensor, orig.tensor).reshape(-1)) -@pytest.mark.parametrize("num_qubits, N", [(randint(2,7), randint(3,10)) for _ in range(3)]) -def test_apply_right_CX(num_qubits, N): - random_kets = [unitary_group.rvs(2**num_qubits)[:,:1] for _ in range(N)] +@pytest.mark.parametrize( + 'num_qubits, N', + [(randint(2, 7), randint(3, 10)) for _ in range(3)], +) +def test_apply_right_CX(num_qubits: int, N: int) -> None: + random_kets = [unitary_group.rvs(2**num_qubits)[:, :1] for _ in range(N)] random_bras = [ket.T.conj() for ket in random_kets] - rhs = LHSTensor(list_of_states = random_bras, num_qudits = num_qubits) + rhs = LHSTensor(list_of_states=random_bras, num_qudits=num_qubits) orig = rhs.copy() H_mat = UnitaryMatrixJax(CXGate().get_unitary()) From 1f8f2740cbb005d91ce18fd8168daa5d186230d8 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 3 Oct 2023 01:08:59 -0700 Subject: [PATCH 22/59] Now also testing the toffoli with sampling --- tests/test_examples.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_examples.py b/tests/test_examples.py index 55be638..0bc5fdf 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -7,12 +7,17 @@ from examples.gate_deletion_syth import run_gate_del_flow_example from examples.toffoli_instantiation import run_toffoli_instantiation +from examples.toffoli_instantiation_using_sampling import run_toffoli_instantiation as run_toffoli_instantiation_using_sampling def test_toffoli_instantiation() -> None: distance = run_toffoli_instantiation() assert distance <= 1e-10 +def test_toffoli_instantiation_using_sampling() -> None: + distance = run_toffoli_instantiation_using_sampling() + assert distance <= 1e-10 + def test_gate_del_synth() -> None: From 3da5fe0abdccbf7f1fd920e918cddabc3d94d6d6 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 6 Oct 2023 16:46:17 -0700 Subject: [PATCH 23/59] Updating the copyrights --- LICENSE | 20 ++++++++------------ README.md | 4 +--- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/LICENSE b/LICENSE index ae4f0e7..1325218 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,5 @@ Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2023, -The Regents of the University of California, through Lawrence -Berkeley National Laboratory (subject to receipt of any required -approvals from the U.S. Dept. of Energy) and Alon Kukliansky. All rights reserved. +U.S. Federal Government and the Government of Israel. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,10 +11,9 @@ this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -(3) Neither the name of the University of California, Lawrence Berkeley -National Laboratory, U.S. Dept. of Energy, Alon Kukliansky nor the names of its -contributors may be used to endorse or promote products derived from this software -without specific prior written permission. +(3) Neither the name of the U.S. Federal Government, the Government of Israel +nor the names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,10 +30,9 @@ POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your -Enhancements available either publicly, or directly to Lawrence Berkeley -National Laboratory, without imposing a separate written license agreement -for such Enhancements, then you hereby grant the following license: a -non-exclusive, royalty-free perpetual license to install, use, modify, -prepare derivative works, incorporate into other computer software, +Enhancements available either publicly without imposing a separate written +license agreement for such Enhancements, then you hereby grant the following +license: a non-exclusive, royalty-free perpetual license to install, use, +modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. diff --git a/README.md b/README.md index b463dc3..7097dbd 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,4 @@ for more information. ## Copyright Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2023, -The Regents of the University of California, through Lawrence -Berkeley National Laboratory (subject to receipt of any required -approvals from the U.S. Dept. of Energy) and Alon Kukliansky. All rights reserved. +U.S. Federal Government and the Government of Israel. All rights reserved. From 758fb936724a6d892bd77cc80208784858b7de04 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 6 Oct 2023 16:48:52 -0700 Subject: [PATCH 24/59] Updating the package name --- tests/test_single_leg_tensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py index 23f9ffa..efe302d 100644 --- a/tests/test_single_leg_tensor.py +++ b/tests/test_single_leg_tensor.py @@ -7,10 +7,10 @@ import pytest from bqskit.ir.gates import CXGate from bqskit.ir.gates import HGate -from bqskitgpu.singlelegedtensor import LHSTensor -from bqskitgpu.singlelegedtensor import RHSTensor -from bqskitgpu.singlelegedtensor import SingleLegSideTensor -from bqskitgpu.unitarymatrixjax import UnitaryMatrixJax +from bqskitqfactorjax.singlelegedtensor import LHSTensor +from bqskitqfactorjax.singlelegedtensor import RHSTensor +from bqskitqfactorjax.singlelegedtensor import SingleLegSideTensor +from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax from scipy.stats import unitary_group From 87a3b1e15468e5d793159502cdc00d4202e26031 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 16 Oct 2023 11:35:27 -0700 Subject: [PATCH 25/59] Fix a bug with type casting --- bqskitqfactorjax/qfactor_sample_jax.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 983974b..4289f55 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -49,7 +49,7 @@ def __init__( min_iters: int = 1000, beta: float = 0.0, amount_of_validation_states: int = 2, - num_params_coeff: float = 1, + num_params_coeff: float = 1.0, overtrain_ratio: float = 1 / 32, ): @@ -160,7 +160,7 @@ def multi_start_instantiate( for g in gates: amount_of_trainng_states += self.num_params_coeff * g.num_params - amount_of_trainng_states = np.round(amount_of_trainng_states) + amount_of_trainng_states = int(np.round(amount_of_trainng_states)) training_states_kets = self.generate_random_states( amount_of_trainng_states, int(np.prod(radixes)), From bd6eb061e19f6f1df0c35bb7fa7129455cb58c79 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 16 Oct 2023 11:37:50 -0700 Subject: [PATCH 26/59] Adding example that demonstrates the speed boost --- examples/adder63_10q_block_47.qasm | 114 +++++ examples/adder63_10q_block_63.qasm | 112 +++++ examples/compare_state_sample_to_orig.py | 106 +++++ examples/heisenberg64_10q_block_036.qasm | 108 +++++ examples/heisenberg64_10q_block_100.qasm | 91 ++++ examples/shor26_10q_block_051.qasm | 341 ++++++++++++++ examples/shor26_10q_block_134.qasm | 537 +++++++++++++++++++++++ job.sh | 24 + 8 files changed, 1433 insertions(+) create mode 100644 examples/adder63_10q_block_47.qasm create mode 100644 examples/adder63_10q_block_63.qasm create mode 100644 examples/compare_state_sample_to_orig.py create mode 100644 examples/heisenberg64_10q_block_036.qasm create mode 100644 examples/heisenberg64_10q_block_100.qasm create mode 100644 examples/shor26_10q_block_051.qasm create mode 100644 examples/shor26_10q_block_134.qasm create mode 100644 job.sh diff --git a/examples/adder63_10q_block_47.qasm b/examples/adder63_10q_block_47.qasm new file mode 100644 index 0000000..1aa2e1f --- /dev/null +++ b/examples/adder63_10q_block_47.qasm @@ -0,0 +1,114 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[6], q[7]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.9269908169872414) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[3], q[4]; +cx q[3], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[5]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[4], q[5]; +u3(0.0, 0.0, 5.497787143782138) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[3], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[9]; +u3(1.5707963267948966, 0.0, 3.9269908169872414) q[8]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[8], q[9]; +cx q[3], q[8]; +cx q[4], q[9]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(0.0, 0.0, 5.497787143782138) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[3], q[8]; +cx q[4], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[4], q[9]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[8], q[9]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[8], q[9]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[2], q[5]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[2], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[2], q[5]; +cx q[1], q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +cx q[1], q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +cx q[1], q[2]; +cx q[0], q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +cx q[0], q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +cx q[0], q[1]; diff --git a/examples/adder63_10q_block_63.qasm b/examples/adder63_10q_block_63.qasm new file mode 100644 index 0000000..9ceb441 --- /dev/null +++ b/examples/adder63_10q_block_63.qasm @@ -0,0 +1,112 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[2], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[2], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[2], q[6]; +cx q[0], q[2]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[0], q[2]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +cx q[0], q[2]; +cx q[5], q[6]; +cx q[0], q[1]; +u3(1.5707963267948966, -1.5707963267948966, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +cx q[4], q[5]; +cx q[0], q[1]; +u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, -4.71238898038469) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +cx q[4], q[5]; +cx q[0], q[1]; +u3(1.5707963267948966, 3.9269908169872414, 0.0) q[4]; +cx q[3], q[4]; +u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[5]; +u3(1.5707963267948966, -3.141592653589793, -1.5707963267948966) q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, -3.141592653589793, 5.497787143782138) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[3], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[5]; +u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, -4.71238898038469) q[4]; +cx q[3], q[4]; +u3(0.0, 0.0, 2.356194490192345) q[3]; +u3(1.5707963267948966, 3.141592653589793, -1.5707963267948966) q[4]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +u3(0.0, 0.0, 5.497787143782138) q[5]; +cx q[4], q[5]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[3], q[4]; +cx q[5], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[3], q[4]; +u3(0.0, 0.0, 4.71238898038469) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[4], q[5]; +u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, -4.71238898038469) q[5]; +cx q[4], q[5]; +u3(1.5707963267948966, 1.5707963267948966, 1.5707963267948966) q[4]; +u3(1.5707963267948966, 0.7853981633974483, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +cx q[5], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[4], q[5]; +u3(0.0, 0.0, 4.71238898038469) q[8]; +u3(1.5707963267948966, 0.0, 7.0685834705770345) q[4]; +u3(3.141592653589793, 1.8237544, 7.3215416) q[5]; +cx q[5], q[8]; +u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, -4.71238898038469) q[8]; +cx q[5], q[8]; +u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[5]; +cx q[4], q[5]; +u3(2.356194490192345, 4.71238898038469, -1.5707963267948966) q[8]; +u3(1.5707963267948966, 2.356194490192345, -3.141592653589793) q[4]; +cx q[8], q[9]; +cx q[3], q[4]; +u3(1.5707963267948966, -2.356194490192345, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +cx q[8], q[9]; +cx q[3], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[8], q[9]; +cx q[3], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[3], q[7]; diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py new file mode 100644 index 0000000..28d82ad --- /dev/null +++ b/examples/compare_state_sample_to_orig.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import sys +import time +from bqskit.ir.circuit import Circuit +from bqskit.compiler import Compiler, CompilationTask +# from inst_pass import InstPass + +from bqskitqfactorjax.qfactor_sample_jax import QFactor_sample_jax +from bqskitqfactorjax.qfactor_jax import QFactor_jax +from bqskit.passes import ToVariablePass + +dist_tol_requested = float(sys.argv[2]) +num_mutlistarts = 32 + +num_params_coeff = int(sys.argv[3]) + + +instantiate_options = { + 'multistarts': num_mutlistarts, + } + + +qfactr_gpu_instantiator = QFactor_jax( + + dist_tol=dist_tol_requested, # Stopping criteria for distance + + max_iters=100000, # Maximum number of iterations + min_iters=1, # Minimum number of iterations + + # One step plateau detection - + # diff_tol_a + diff_tol_r ∗ |c(i)| <= |c(i)|-|c(i-1)| + diff_tol_a=0.0, # Stopping criteria for distance change + diff_tol_r=1e-10, # Relative criteria for distance change + + # Long plateau detection - + # diff_tol_step_r*|c(i-diff_tol_step)| <= |c(i)|-|c(i-diff_tol_step)| + diff_tol_step_r=0.1, # The relative improvement expected + diff_tol_step=200, # The interval in which to check the improvement + + # Regularization parameter - [0.0 - 1.0] + # Increase to overcome local minima at the price of longer compute + beta=0.0, +) + + +qfactr_sample_gpu_instantiator = QFactor_sample_jax( + + dist_tol=dist_tol_requested, # Stopping criteria for distance + + max_iters=100000, # Maximum number of iterations + min_iters=10, # Minimum number of iterations + + # Regularization parameter - [0.0 - 1.0] + # Increase to overcome local minima at the price of longer compute + beta=0.0, + + amount_of_validation_states=2, + num_params_coeff=num_params_coeff, # indicates the ratio between the sum of parameters in the circuits to the sample size. + overtrain_ratio=1 / 32, +) + +# file_name = 'heisenberg64_10q_block_100.qasm' +# file_name = 'heisenberg64_10q_block_036.qasm' +file_name = sys.argv[1] +# orig_10q_block_cir = Circuit.from_file('adder63_10q_block_47.qasm') +# orig_10q_block_cir = Circuit.from_file('adder63_10q_block_63.qasm') + +print(f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coeff = }') + +orig_10q_block_cir = Circuit.from_file(f'examples/{file_name}') + +with Compiler(num_workers=1) as compiler: + task = CompilationTask(orig_10q_block_cir, [ToVariablePass()]) + task_id = compiler.submit(task) + orig_10q_block_cir_vu = compiler.result(task_id) + + +tic = time.perf_counter() +target = orig_10q_block_cir_vu.get_unitary() +time_to_simulate_circ = time.perf_counter() - tic +print(f"Time to simulate was {time_to_simulate_circ}") + +tic = time.perf_counter() +orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_sample_gpu_instantiator) +sample_inst_time = time.perf_counter() - tic +inst_sample_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) + +print(f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coeff = }') + +tic = time.perf_counter() +orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_gpu_instantiator) +full_inst_time = time.perf_counter() - tic +inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) + +print(f'full method {full_inst_time = } {inst_dist_from_target = }') + +# with Compiler(num_workers=num_mutlistarts+1) as compiler: +# task = CompilationTask(orig_10q_block_cir, [InstPass(instantiate_options, target)]) +# tic = time.perf_counter() +# task_id = compiler.submit(task) +# circ = compiler.result(task_id) # type: ignore +# ceres_inst_time = time.perf_counter() - tic +# ceres_inst_dist_from_target = circ.get_unitary().get_distance_from(target, 1) + +# print(f'CERES inst {ceres_inst_time = } {ceres_inst_dist_from_target = }') \ No newline at end of file diff --git a/examples/heisenberg64_10q_block_036.qasm b/examples/heisenberg64_10q_block_036.qasm new file mode 100644 index 0000000..43b2f4e --- /dev/null +++ b/examples/heisenberg64_10q_block_036.qasm @@ -0,0 +1,108 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[3]; +cx q[2], q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[9]; +u3(0.0, 0.0, 0.02) q[3]; +cx q[2], q[3]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[2]; +u3(0.0, 1.406583, -1.406583) q[3]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, 0.0, 0.02) q[2]; +u3(0.0, 0.0, 0.02) q[4]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[3]; +u3(0.0, 1.406583, -1.406583) q[4]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.04) q[1]; +u3(0.0, 0.0, 0.02) q[3]; +u3(0.0, 0.0, 0.02) q[5]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[4]; +u3(0.0, 1.406583, -1.406583) q[5]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(0.0, 0.0, 0.04) q[2]; +u3(0.0, 0.0, 0.02) q[4]; +u3(0.0, 0.0, 0.02) q[6]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[5]; +u3(0.0, 1.406583, -1.406583) q[6]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, 0.0, 0.04) q[3]; +u3(0.0, 0.0, 0.02) q[5]; +u3(0.0, 0.0, 0.02) q[7]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[6]; +u3(0.0, 1.406583, -1.406583) q[7]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.04) q[4]; +u3(0.0, 0.0, 0.02) q[6]; +u3(0.0, 0.0, 0.02) q[8]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[7]; +u3(0.0, 1.406583, -1.406583) q[8]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.04) q[5]; +u3(0.0, 0.0, 0.02) q[7]; +u3(0.0, 0.0, 0.02) q[9]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[8]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, 1.406583, -1.406583) q[9]; +u3(0.0, 0.0, 0.04) q[6]; +u3(0.0, 0.0, 0.02) q[8]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +cx q[6], q[7]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[8]; +u3(0.0, 0.0, 0.04) q[7]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; diff --git a/examples/heisenberg64_10q_block_100.qasm b/examples/heisenberg64_10q_block_100.qasm new file mode 100644 index 0000000..e8aa92f --- /dev/null +++ b/examples/heisenberg64_10q_block_100.qasm @@ -0,0 +1,91 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[2]; +cx q[1], q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +u3(0.0, 0.0, 0.02) q[2]; +cx q[1], q[2]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[1]; +u3(0.0, 1.406583, -1.406583) q[2]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.0, 0.0, 0.02) q[1]; +u3(0.0, 0.0, 0.02) q[3]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[0]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[2]; +u3(0.0, 1.406583, -1.406583) q[3]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, 0.0, 0.02) q[2]; +u3(0.0, 0.0, 0.02) q[4]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[3]; +u3(0.0, 1.406583, -1.406583) q[4]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.02) q[3]; +u3(0.0, 0.0, 0.02) q[5]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[4]; +u3(0.0, 1.406583, -1.406583) q[5]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(0.0, 0.0, 0.02) q[4]; +u3(0.0, 0.0, 0.02) q[6]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[5]; +u3(0.0, 1.406583, -1.406583) q[6]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, 0.0, 0.02) q[5]; +u3(0.0, 0.0, 0.02) q[7]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[6]; +u3(0.0, 1.406583, -1.406583) q[7]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.02) q[6]; +u3(0.0, 0.0, 0.02) q[8]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[7]; +u3(0.0, 1.406583, -1.406583) q[8]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.02) q[7]; +u3(0.0, 0.0, 0.02) q[9]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[8]; +cx q[7], q[8]; +u3(0.0, 1.406583, -1.406583) q[9]; +u3(0.0, 0.0, 0.02) q[8]; +cx q[7], q[8]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +u3(0.0, -3.141592653589793, -3.141592653589793) q[8]; diff --git a/examples/shor26_10q_block_051.qasm b/examples/shor26_10q_block_051.qasm new file mode 100644 index 0000000..e1c763a --- /dev/null +++ b/examples/shor26_10q_block_051.qasm @@ -0,0 +1,341 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[1], q[8]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.35588354) q[0]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.92730176717959) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.71176709) q[0]; +u3(0.0, 0.0, 5.92730175358979) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.57141821717959) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.4235342) q[0]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 4.85965110717959) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.276272) q[0]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.00691330717959) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.9817477042468103) q[0]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.30143760293278) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[2]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[0], q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[0], q[2]; +cx q[1], q[8]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[2]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.35588354) q[8]; +u3(0.0, 0.0, 5.92730176717959) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.35588354) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.57141821717959) q[0]; +u3(0.0, 0.0, 0.3558835) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.71176709) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 4.85965110717959) q[0]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.4235342) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.00691330717959) q[0]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.276272) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.30143760293278) q[0]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.9817477042468103) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +cx q[1], q[2]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[1], q[2]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[2]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[0], q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[0], q[2]; +cx q[1], q[8]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[2]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +u3(0.0, 0.0, 0.35588354) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[0], q[8]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.92730176717959) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.35588354) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.71176709) q[0]; +u3(0.0, 0.0, 5.92730176717959) q[8]; +cx q[0], q[7]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.57141821717959) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.71176709) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.4235342) q[0]; +u3(0.0, 0.0, 5.57141821717959) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 4.85965110717959) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 1.4235342) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 1.276272) q[0]; +u3(0.0, 0.0, 4.85965110717959) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.00691330717959) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 1.276272) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.9817477042468103) q[0]; +u3(0.0, 0.0, 5.00691330717959) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.30143760293278) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.9817477042468103) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +u3(0.0, 0.0, 5.30143760293278) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.39269908169872414) q[3]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.890486225480862) q[3]; +cx q[0], q[2]; +u3(0.0, 0.0, 5.497787143782138) q[2]; +cx q[0], q[2]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[0], q[2]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[0], q[2]; +u3(0.0, 0.0, 5.497787143782138) q[2]; diff --git a/examples/shor26_10q_block_134.qasm b/examples/shor26_10q_block_134.qasm new file mode 100644 index 0000000..c0b7e6c --- /dev/null +++ b/examples/shor26_10q_block_134.qasm @@ -0,0 +1,537 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[1], q[8]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.25864161457342) q[0]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.02454369260617026) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +u3(0.0, 0.0, 0.0245436999999999) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[0], q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[0], q[3]; +cx q[1], q[8]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[3]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +u3(0.0, 0.0, 0.02454369260617026) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.25864161457342) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +u3(0.0, 0.0, 6.25864165358979) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[0], q[3]; +cx q[1], q[8]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[3]; +cx q[1], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +u3(0.0, 0.0, 6.25864161457342) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.02454369260617026) q[0]; +cx q[1], q[7]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[1], q[7]; +u3(0.0, 0.0, 6.25864161457342) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +u3(0.0, 0.0, 0.02454369260617026) q[8]; +cx q[0], q[7]; +cx q[2], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[7]; +cx q[2], q[8]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +cx q[1], q[6]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[1], q[6]; +u3(0.0, 0.0, 6.23409792196725) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[6]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +cx q[1], q[5]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[1], q[5]; +u3(0.0, 0.0, 6.18501053675491) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[5]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +cx q[1], q[4]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[1], q[4]; +u3(0.0, 0.0, 6.08683576633022) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[4]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[1], q[3]; +u3(0.0, 0.0, 5.890486225480862) q[4]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[4]; +cx q[0], q[3]; +u3(0.0, 0.0, 0.7853981633974483) q[3]; +cx q[0], q[3]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[0], q[3]; +u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[1]; +u3(0.0, 0.0, 5.497787143782138) q[3]; +cx q[0], q[3]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +u3(10.995574287564276, 0.0, 2.356194490192345) q[3]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[8]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +cx q[2], q[7]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[2], q[7]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +u3(0.0, 0.0, 0.0490873732051035) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +cx q[2], q[6]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[2], q[6]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +cx q[2], q[5]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[2], q[5]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +cx q[2], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[2], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[0], q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[0], q[4]; +cx q[2], q[8]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[4]; +cx q[2], q[8]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[8]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +cx q[2], q[7]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[2], q[7]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +u3(0.0, 0.0, 6.23409795358979) q[8]; +cx q[0], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +cx q[2], q[6]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[2], q[6]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +cx q[2], q[5]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[2], q[5]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +cx q[2], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[2], q[4]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[0], q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[0], q[4]; +cx q[2], q[8]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[4]; +cx q[2], q[8]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +u3(0.0, 0.0, 6.23409792196725) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[8]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[0]; +cx q[2], q[7]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[2], q[7]; +u3(0.0, 0.0, 6.23409792196725) q[8]; +cx q[0], q[8]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.18501053675491) q[0]; +u3(0.0, 0.0, 0.04908738521234052) q[8]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[7]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[0]; +cx q[2], q[6]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[2], q[6]; +u3(0.0, 0.0, 6.18501053675491) q[7]; +cx q[0], q[7]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 6.08683576633022) q[0]; +u3(0.0, 0.0, 0.09817477042468103) q[7]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[6]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[0]; +cx q[2], q[5]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[2], q[5]; +u3(0.0, 0.0, 6.08683576633022) q[6]; +cx q[0], q[6]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.890486225480862) q[0]; +u3(0.0, 0.0, 0.19634954084936207) q[6]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[5]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[0]; +cx q[2], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[2], q[4]; +u3(0.0, 0.0, 5.890486225480862) q[5]; +cx q[0], q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 5.497787143782138) q[0]; +u3(0.0, 0.0, 0.39269908169872414) q[5]; +cx q[0], q[4]; +u3(0.0, 0.0, 0.7853981633974483) q[4]; +cx q[0], q[4]; +cx q[2], q[0]; +u3(0.0, 0.0, 0.7853981633974483) q[0]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[0], q[4]; +u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[2]; +u3(0.0, 0.0, 5.497787143782138) q[4]; +cx q[0], q[4]; +u3(10.995574287564276, 0.0, 2.356194490192345) q[4]; diff --git a/job.sh b/job.sh new file mode 100644 index 0000000..e6da050 --- /dev/null +++ b/job.sh @@ -0,0 +1,24 @@ +#!/bin/bash +#SBATCH --job-name=checking_run_time_var +#SBATCH -A m4141_g +#SBATCH -C gpu +#SBATCH -q regular +#SBATCH -t 8:50:00 +#SBATCH -n 1 +#SBATCH --mem=0 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-task=1 +#SBATCH --output=./logs/comparing_full_and_sample-shor_10q-%j.txt + + + + +date +uname -a +module load python +module load nvidia +conda activate my_env +nvidia-cuda-mps-control -d + + +XLA_PYTHON_CLIENT_PREALLOCATE=False python ./examples/compare_state_sample_to_orig.py examples/shor26_10q_block_134.qasm 1e-9 0.05 \ No newline at end of file From a6e6fef8b581a1e9a2c090a05de1500652c89921 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 16 Oct 2023 13:12:13 -0700 Subject: [PATCH 27/59] Fixing the wrong convertion --- examples/compare_state_sample_to_orig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index 28d82ad..38cef1f 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -13,7 +13,7 @@ dist_tol_requested = float(sys.argv[2]) num_mutlistarts = 32 -num_params_coeff = int(sys.argv[3]) +num_params_coeff = float(sys.argv[3]) instantiate_options = { From 855d8d6c3190c713683719c84514938760539efb Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Thu, 19 Oct 2023 11:24:56 -0700 Subject: [PATCH 28/59] Renaming the Class --- bqskitqfactorjax/qfactor_sample_jax.py | 2 +- examples/compare_state_sample_to_orig.py | 8 ++++---- examples/toffoli_instantiation_using_sampling.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 4289f55..367650b 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -40,7 +40,7 @@ jax.config.update('jax_enable_x64', True) -class QFactor_sample_jax(Instantiater): +class QFactorSampleJax(Instantiater): def __init__( self, diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index 38cef1f..e04798f 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -6,7 +6,7 @@ from bqskit.compiler import Compiler, CompilationTask # from inst_pass import InstPass -from bqskitqfactorjax.qfactor_sample_jax import QFactor_sample_jax +from bqskitqfactorjax.qfactor_sample_jax import QFactorSampleJax from bqskitqfactorjax.qfactor_jax import QFactor_jax from bqskit.passes import ToVariablePass @@ -44,7 +44,7 @@ ) -qfactr_sample_gpu_instantiator = QFactor_sample_jax( +qfactr_sample_gpu_instantiator = QFactorSampleJax( dist_tol=dist_tol_requested, # Stopping criteria for distance @@ -68,7 +68,7 @@ print(f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coeff = }') -orig_10q_block_cir = Circuit.from_file(f'examples/{file_name}') +orig_10q_block_cir = Circuit.from_file(f'{file_name}') with Compiler(num_workers=1) as compiler: task = CompilationTask(orig_10q_block_cir, [ToVariablePass()]) @@ -103,4 +103,4 @@ # ceres_inst_time = time.perf_counter() - tic # ceres_inst_dist_from_target = circ.get_unitary().get_distance_from(target, 1) -# print(f'CERES inst {ceres_inst_time = } {ceres_inst_dist_from_target = }') \ No newline at end of file +# print(f'CERES inst {ceres_inst_time = } {ceres_inst_dist_from_target = }') diff --git a/examples/toffoli_instantiation_using_sampling.py b/examples/toffoli_instantiation_using_sampling.py index 431efc7..ae5a8cc 100644 --- a/examples/toffoli_instantiation_using_sampling.py +++ b/examples/toffoli_instantiation_using_sampling.py @@ -11,11 +11,11 @@ from bqskit.ir.gates import VariableUnitaryGate from bqskit.qis.unitary import UnitaryMatrix -from bqskitqfactorjax.qfactor_sample_jax import QFactor_sample_jax +from bqskitqfactorjax.qfactor_sample_jax import QFactorSampleJax def run_toffoli_instantiation(dist_tol_requested: float = 1e-10) -> float: - qfactr_gpu_instantiator = QFactor_sample_jax( + qfactr_gpu_instantiator = QFactorSampleJax( dist_tol=dist_tol_requested, # Stopping criteria for distance From 688af23fcfc0ca7d93687dc0a6adb81971018675 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 23 Oct 2023 13:50:18 -0700 Subject: [PATCH 29/59] some typos fix Changing the type of the counter to be int --- bqskitqfactorjax/qfactor_sample_jax.py | 13 +++++++------ examples/compare_state_sample_to_orig.py | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 367650b..867198a 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -309,11 +309,12 @@ def _loop_vmaped_state_sample_sweep( gates: tuple[Gate, ...], untrys: Array, dist_tol: float, max_iters: int, beta: float, amount_of_starts: int, min_iters: int, - overtrian_ratio: float, + overtrain_ratio: float, training_states_kets: Array, validation_states_kets: Array, ) -> tuple[Array, Array[float], Array[float], Array[int]]: + # Calculate the bras for the validation and training states validation_states_bras = jax.vmap( lambda ket: ket.T.conj(), )(jnp.array(validation_states_kets)) @@ -345,7 +346,7 @@ def _loop_vmaped_state_sample_sweep( num_qudits=num_qudits, radixes=radixes, ) - # In JAX the body of a while must be a function that accepet and returns + # In JAX the body of a while must be a function that accepts and returns # the same type, and also the check should be a function that accepts it # and return a boolean @@ -365,8 +366,8 @@ def should_continue( reached_max_iteration = iteration_counts[0] > max_iters above_min_iteration = iteration_counts[0] > min_iters - any_reached_over_training = jnp.any( - training_costs < overtrian_ratio * validation_costs, + all_reached_over_training = jnp.all( + overtrain_ratio * validation_costs > training_costs, ) return jnp.logical_not( @@ -376,7 +377,7 @@ def should_continue( reached_max_iteration, jnp.logical_and( above_min_iteration, - any_reached_over_training, + all_reached_over_training, ), ), ), @@ -429,7 +430,7 @@ def _while_body_to_be_vmaped( untrys, jnp.ones(amount_of_starts), # train_cost jnp.ones(amount_of_starts), # val_cost - jnp.zeros(amount_of_starts), # iter_count + jnp.zeros(amount_of_starts, dtype=int), # iter_count ) r = jax.lax.while_loop(should_continue, while_body_vmaped, initial_loop_var) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index e04798f..99eb819 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -11,7 +11,7 @@ from bqskit.passes import ToVariablePass dist_tol_requested = float(sys.argv[2]) -num_mutlistarts = 32 +num_mutlistarts = 16 num_params_coeff = float(sys.argv[3]) @@ -21,7 +21,7 @@ } -qfactr_gpu_instantiator = QFactor_jax( +qfactor_gpu_instantiator = QFactor_jax( dist_tol=dist_tol_requested, # Stopping criteria for distance @@ -44,12 +44,12 @@ ) -qfactr_sample_gpu_instantiator = QFactorSampleJax( +qfactor_sample_gpu_instantiator = QFactorSampleJax( dist_tol=dist_tol_requested, # Stopping criteria for distance - max_iters=100000, # Maximum number of iterations - min_iters=10, # Minimum number of iterations + max_iters=2, # Maximum number of iterations + min_iters=1, # Minimum number of iterations # Regularization parameter - [0.0 - 1.0] # Increase to overcome local minima at the price of longer compute @@ -82,18 +82,18 @@ print(f"Time to simulate was {time_to_simulate_circ}") tic = time.perf_counter() -orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_sample_gpu_instantiator) +orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactor_sample_gpu_instantiator) sample_inst_time = time.perf_counter() - tic inst_sample_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) print(f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coeff = }') -tic = time.perf_counter() -orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_gpu_instantiator) -full_inst_time = time.perf_counter() - tic -inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) +# tic = time.perf_counter() +# orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_gpu_instantiator) +# full_inst_time = time.perf_counter() - tic +# inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) -print(f'full method {full_inst_time = } {inst_dist_from_target = }') +# print(f'full method {full_inst_time = } {inst_dist_from_target = }') # with Compiler(num_workers=num_mutlistarts+1) as compiler: # task = CompilationTask(orig_10q_block_cir, [InstPass(instantiate_options, target)]) From a9cd7b3cb5303f13651758161ca15676dae6e234 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 24 Oct 2023 15:55:17 -0700 Subject: [PATCH 30/59] Adding plateau detection Adding overtraning detection Adding a hueristic to double the training set until no over training some name changes --- bqskitqfactorjax/qfactor_sample_jax.py | 270 ++++++++++++------ .../toffoli_instantiation_using_sampling.py | 4 +- 2 files changed, 179 insertions(+), 95 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 867198a..9f4ba35 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -49,8 +49,11 @@ def __init__( min_iters: int = 1000, beta: float = 0.0, amount_of_validation_states: int = 2, - num_params_coeff: float = 1.0, - overtrain_ratio: float = 1 / 32, + num_params_coef: float = 1.0, + overtrain_relative_threshold: float = 0.1, + diff_tol_r: float=1e-4, # Relative criteria for distance change + plateau_windows_size: int = 6, + exact_amount_of_states_to_train_on: int | None = None, ): if not isinstance(dist_tol, float) or dist_tol > 0.5: @@ -68,8 +71,11 @@ def __init__( self.beta = beta self.amount_of_validation_states = amount_of_validation_states - self.num_params_coeff = num_params_coeff - self.overtrain_ratio = overtrain_ratio + self.num_params_coef = num_params_coef + self.overtrain_ratio = overtrain_relative_threshold + self.diff_tol_r = diff_tol_r + self.plateau_windows_size = plateau_windows_size + self.exact_amount_of_states_to_train_on = exact_amount_of_states_to_train_on def instantiate( self, @@ -132,72 +138,130 @@ def multi_start_instantiate( radixes = target.radixes num_qudits = target.num_qudits - untrys = [] - - for gate in gates: - size_of_untry = 2**gate.num_qudits - - if isinstance(gate, VariableUnitaryGateAcc): - pre_padding_untrys = [ - unitary_group.rvs(size_of_untry) for - _ in range(num_starts) - ] - else: - pre_padding_untrys = [ - gate.get_unitary().numpy for - _ in range(num_starts) - ] - - untrys.append([ - _apply_padding_and_flatten( - pre_padd, gate, biggest_gate_size, - ) for pre_padd in pre_padding_untrys - ]) - - untrys = jnp.array(np.stack(untrys, axis=1)) - - amount_of_trainng_states = 0 - for g in gates: - amount_of_trainng_states += self.num_params_coeff * g.num_params + + # Initial number of states to use can b + if self.exact_amount_of_states_to_train_on is None: + amount_of_params_in_circuit = 0 + for g in gates: + amount_of_params_in_circuit += g.num_params + initial_amount_of_training_states = int( + np.sqrt(amount_of_params_in_circuit) * self.num_params_coef + ) + else: + initial_amount_of_training_states =\ + self.exact_amount_of_states_to_train_on - amount_of_trainng_states = int(np.round(amount_of_trainng_states)) + amount_of_training_states = initial_amount_of_training_states - training_states_kets = self.generate_random_states( - amount_of_trainng_states, int(np.prod(radixes)), - ) validation_states_kets = self.generate_random_states( - self.amount_of_validation_states, int(np.prod(radixes)), - ) - - final_untrys, training_costs, validation_costs, iteration_counts = \ - _jited_loop_vmaped_state_sample_sweep( - target, num_qudits, radixes, locations, gates, untrys, - self.dist_tol, self.max_iters, self.beta, - num_starts, self.min_iters, self.overtrain_ratio, - training_states_kets, validation_states_kets, + self.amount_of_validation_states, int(np.prod(radixes)), ) - it = iteration_counts[0] - untrys = final_untrys - best_start = jnp.argmin(training_costs) - if any(training_costs < self.dist_tol): - _logger.debug( - f'Terminated: {it} c1 = {training_costs} <= dist_tol.\n' - f'Best start is {best_start}', - ) - elif all(validation_costs > self.overtrain_ratio * training_costs): - _logger.debug( - f'Terminated: {it} overtraining detected in all multistarts', - ) - elif it >= self.max_iters: - _logger.debug('Terminated: iteration limit reached.') - else: - _logger.error( - f'Terminated with no good reason after {it} iterstion ' - f'with c1s {training_costs}.', + generate_untrys_only_once = 'GEN_ONCE' in os.environ + + if generate_untrys_only_once: + untrys = [] + + for gate in gates: + size_of_untry = 2**gate.num_qudits + + if isinstance(gate, VariableUnitaryGateAcc): + pre_padding_untrys = [ + unitary_group.rvs(size_of_untry) for + _ in range(num_starts) + ] + else: + pre_padding_untrys = [ + gate.get_unitary().numpy for + _ in range(num_starts) + ] + + untrys.append([ + _apply_padding_and_flatten( + pre_padd, gate, biggest_gate_size, + ) for pre_padd in pre_padding_untrys + ]) + + untrys = jnp.array(np.stack(untrys, axis=1)) + + have_sufficient_states = False + should_double_the_training_size = True + while not have_sufficient_states: + + if not generate_untrys_only_once: + untrys = [] + + for gate in gates: + size_of_untry = 2**gate.num_qudits + + if isinstance(gate, VariableUnitaryGateAcc): + pre_padding_untrys = [ + unitary_group.rvs(size_of_untry) for + _ in range(num_starts) + ] + else: + pre_padding_untrys = [ + gate.get_unitary().numpy for + _ in range(num_starts) + ] + + untrys.append([ + _apply_padding_and_flatten( + pre_padd, gate, biggest_gate_size, + ) for pre_padd in pre_padding_untrys + ]) + + untrys = jnp.array(np.stack(untrys, axis=1)) + + + + training_states_kets = self.generate_random_states( + amount_of_training_states, int(np.prod(radixes)), ) + final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows = \ + _jited_loop_vmaped_state_sample_sweep( + target, num_qudits, radixes, locations, gates, untrys, + self.dist_tol, self.max_iters, self.beta, + num_starts, self.min_iters, self.diff_tol_r, + self.plateau_windows_size, self.overtrain_ratio, + training_states_kets, validation_states_kets, + ) + + it = iteration_counts[0] + untrys = final_untrys + best_start = jnp.argmin(training_costs) + + have_sufficient_states = True + if any(training_costs < self.dist_tol): + _logger.debug( + f'Terminated: {it} c1 = {training_costs} <= dist_tol.\n' + f'Best start is {best_start}', + ) + elif it >= self.max_iters: + _logger.debug(f'Terminated {it}: iteration limit reached. c1 = {training_costs}') + elif it > self.min_iters: + if all(validation_costs - training_costs > self.overtrain_ratio * training_costs): + _logger.debug( + f'Terminated: {it} overtraining detected in all multistarts', + ) + have_sufficient_states = False + elif np.all(np.all(plateau_windows, axis=1)): + _logger.debug( + f'Terminated: {it} plateau detected in all multistarts c1 = {training_costs}', + ) + else: + _logger.error( + f'Terminated with no good reason after {it} iterations ' + f'with c1s {training_costs}.', + ) + + if should_double_the_training_size: + amount_of_training_states *= 2 + else: + amount_of_training_states += initial_amount_of_training_states + params: list[Sequence[float]] = [] for untry, gate in zip(untrys[best_start], gates): if isinstance(gate, ConstantGate): @@ -300,6 +364,7 @@ def generate_random_states( for i in range(states_to_add_in_step): states_kets.append(rand_unitary[:, i:i + 1]) states_to_add -= states_to_add_in_step + return states_kets @@ -309,8 +374,8 @@ def _loop_vmaped_state_sample_sweep( gates: tuple[Gate, ...], untrys: Array, dist_tol: float, max_iters: int, beta: float, amount_of_starts: int, min_iters: int, - overtrain_ratio: float, - training_states_kets: Array, + diff_tol_r:float, plateau_windows_size:int, + overtrain_ratio: float, training_states_kets: Array, validation_states_kets: Array, ) -> tuple[Array, Array[float], Array[float], Array[int]]: @@ -352,10 +417,10 @@ def _loop_vmaped_state_sample_sweep( def should_continue( loop_var: tuple[ - Array, Array[float], Array[float], Array[int], + Array, Array[float], Array[float], Array[int],Array[bool] ], ) -> Array[bool]: - _, training_costs, validation_costs, iteration_counts = loop_var + _, training_costs, validation_costs, iteration_counts, plateau_windows = loop_var any_reached_required_tol = jnp.any( jax.vmap( @@ -367,7 +432,11 @@ def should_continue( above_min_iteration = iteration_counts[0] > min_iters all_reached_over_training = jnp.all( - overtrain_ratio * validation_costs > training_costs, + validation_costs - training_costs > overtrain_ratio * training_costs, + ) + + all_reached_plateau = jnp.all( + jnp.all(plateau_windows, axis=1) ) return jnp.logical_not( @@ -377,7 +446,10 @@ def should_continue( reached_max_iteration, jnp.logical_and( above_min_iteration, - all_reached_over_training, + jnp.logical_or( + all_reached_over_training, + all_reached_plateau + ) ), ), ), @@ -385,43 +457,52 @@ def should_continue( def _while_body_to_be_vmaped( loop_var: tuple[ - Array, Array[float], Array[float], Array[int], + Array, Array[float], Array[float], Array[int], Array[bool] ], ) -> tuple[ Array, Array[float], Array[float], Array[int], ]: - untrys, training_cost, validation_cost, iteration_count = loop_var + untrys, training_cost, validation_cost, iteration_count, plateau_window = loop_var - untrys_as_matrixs: list[UnitaryMatrixJax] = [] + untrys_as_matrixes: list[UnitaryMatrixJax] = [] for gate_index, gate in enumerate(gates): - untrys_as_matrixs.append( + untrys_as_matrixes.append( UnitaryMatrixJax( _remove_padding_and_create_matrix( untrys[gate_index], gate, ), gate.radixes, ), ) + prev_training_cost = training_cost - untrys_as_matrixs, training_cost, validation_cost =\ + untrys_as_matrixes, training_cost, validation_cost =\ state_sample_single_sweep( - locations, gates, untrys_as_matrixs, + locations, gates, untrys_as_matrixes, beta, A_train, A_val, B0_train, B0_val, ) iteration_count += 1 + have_detected_plateau_in_curr_iter = jnp.abs( + prev_training_cost - training_cost + ) <= diff_tol_r * jnp.abs(training_cost) + + plateau_window = jnp.concatenate( + (jnp.array([have_detected_plateau_in_curr_iter]), plateau_window[:-1]), + ) + biggest_gate_size = max(gate.num_qudits for gate in gates) final_untrys_padded = jnp.array([ _apply_padding_and_flatten( untry.numpy.flatten( ), gate, biggest_gate_size, - ) for untry, gate in zip(untrys_as_matrixs, gates) + ) for untry, gate in zip(untrys_as_matrixes, gates) ]) return ( final_untrys_padded, training_cost, validation_cost, - iteration_count, + iteration_count, plateau_window ) while_body_vmaped = jax.vmap(_while_body_to_be_vmaped) @@ -431,12 +512,26 @@ def _while_body_to_be_vmaped( jnp.ones(amount_of_starts), # train_cost jnp.ones(amount_of_starts), # val_cost jnp.zeros(amount_of_starts, dtype=int), # iter_count + np.zeros((amount_of_starts, plateau_windows_size), dtype=bool) ) - r = jax.lax.while_loop(should_continue, while_body_vmaped, initial_loop_var) - final_untrys, training_costs, validation_costs, iteration_counts = r - - return final_untrys, training_costs, validation_costs, iteration_counts + if 'PRINT_LOSS_QFACTOR' in os.environ: + loop_var = initial_loop_var + i = 1 + while should_continue(loop_var): + loop_var = while_body_vmaped(loop_var) + + untrys, training_costs, validation_costs, iteration_counts, plateau_windows = loop_var + print(f'TRAINLOSS{i}:', training_costs) + print(f'VALLOSS{i}:', validation_costs) + i += 1 + r = loop_var + else: + r = jax.lax.while_loop(should_continue, while_body_vmaped, initial_loop_var) + + final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows = r + + return final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows def state_sample_single_sweep( @@ -453,17 +548,6 @@ def state_sample_single_sweep( B.append(B[-1].copy()) B[-1].apply_right(utry, location) - temp = B[-1].copy() - temp.apply_right(untrys[-1], locations[-1]) - training_cost = 2 * ( - 1 - jnp.real( - SingleLegSideTensor.calc_env( - temp, - A_train, [], - )[0], - ) / A_train.single_leg_radix - ) - # iterate over every gate from right to left and update it new_untrys_rev: list[UnitaryMatrixJax] = [] a_train: RHSTensor = A_train.copy() @@ -503,11 +587,11 @@ def calc_cost(A: RHSTensor, B0: LHSTensor, a: RHSTensor) -> float: return jnp.squeeze(cost) -if 'NO_JIT_QFACTOR' in os.environ: +if 'NO_JIT_QFACTOR' in os.environ or 'PRINT_LOSS_QFACTOR' in os.environ: _jited_loop_vmaped_state_sample_sweep = _loop_vmaped_state_sample_sweep else: _jited_loop_vmaped_state_sample_sweep = jax.jit( _loop_vmaped_state_sample_sweep, static_argnums=( - 1, 2, 3, 4, 6, 7, 8, 9, 10, + 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 ), ) diff --git a/examples/toffoli_instantiation_using_sampling.py b/examples/toffoli_instantiation_using_sampling.py index ae5a8cc..e598928 100644 --- a/examples/toffoli_instantiation_using_sampling.py +++ b/examples/toffoli_instantiation_using_sampling.py @@ -27,8 +27,8 @@ def run_toffoli_instantiation(dist_tol_requested: float = 1e-10) -> float: beta=0.0, amount_of_validation_states=2, - num_params_coeff=1, - overtrain_ratio=1 / 32, + num_params_coef=1, + overtrain_relative_threshold=0.1, ) # We will optimize towards the Toffoli unitary. From c1e73e7027904e01ee9197509f1f93871c3c4468 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 24 Oct 2023 23:17:15 -0700 Subject: [PATCH 31/59] pre-commit fixes --- bqskitqfactorjax/qfactor_sample_jax.py | 118 +++++++++++++++---------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/bqskitqfactorjax/qfactor_sample_jax.py b/bqskitqfactorjax/qfactor_sample_jax.py index 9f4ba35..b60659f 100644 --- a/bqskitqfactorjax/qfactor_sample_jax.py +++ b/bqskitqfactorjax/qfactor_sample_jax.py @@ -37,6 +37,7 @@ _logger = logging.getLogger(__name__) + jax.config.update('jax_enable_x64', True) @@ -51,7 +52,7 @@ def __init__( amount_of_validation_states: int = 2, num_params_coef: float = 1.0, overtrain_relative_threshold: float = 0.1, - diff_tol_r: float=1e-4, # Relative criteria for distance change + diff_tol_r: float = 1e-4, # Relative criteria for distance change plateau_windows_size: int = 6, exact_amount_of_states_to_train_on: int | None = None, ): @@ -75,7 +76,8 @@ def __init__( self.overtrain_ratio = overtrain_relative_threshold self.diff_tol_r = diff_tol_r self.plateau_windows_size = plateau_windows_size - self.exact_amount_of_states_to_train_on = exact_amount_of_states_to_train_on + self.exact_amount_of_states_to_train_on =\ + exact_amount_of_states_to_train_on def instantiate( self, @@ -120,6 +122,7 @@ def multi_start_instantiate( target: UnitaryLike | StateLike | StateSystemLike, num_starts: int, ) -> npt.NDArray[np.float64]: + if len(circuit) == 0: return np.array([]) @@ -138,14 +141,13 @@ def multi_start_instantiate( radixes = target.radixes num_qudits = target.num_qudits - # Initial number of states to use can b if self.exact_amount_of_states_to_train_on is None: amount_of_params_in_circuit = 0 for g in gates: - amount_of_params_in_circuit += g.num_params + amount_of_params_in_circuit += g.num_params initial_amount_of_training_states = int( - np.sqrt(amount_of_params_in_circuit) * self.num_params_coef + np.sqrt(amount_of_params_in_circuit) * self.num_params_coef, ) else: initial_amount_of_training_states =\ @@ -154,9 +156,8 @@ def multi_start_instantiate( amount_of_training_states = initial_amount_of_training_states validation_states_kets = self.generate_random_states( - self.amount_of_validation_states, int(np.prod(radixes)), - ) - + self.amount_of_validation_states, int(np.prod(radixes)), + ) generate_untrys_only_once = 'GEN_ONCE' in os.environ @@ -184,11 +185,11 @@ def multi_start_instantiate( ]) untrys = jnp.array(np.stack(untrys, axis=1)) - + have_sufficient_states = False should_double_the_training_size = True while not have_sufficient_states: - + if not generate_untrys_only_once: untrys = [] @@ -214,20 +215,20 @@ def multi_start_instantiate( untrys = jnp.array(np.stack(untrys, axis=1)) - - training_states_kets = self.generate_random_states( amount_of_training_states, int(np.prod(radixes)), ) - final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows = \ - _jited_loop_vmaped_state_sample_sweep( - target, num_qudits, radixes, locations, gates, untrys, - self.dist_tol, self.max_iters, self.beta, - num_starts, self.min_iters, self.diff_tol_r, - self.plateau_windows_size, self.overtrain_ratio, - training_states_kets, validation_states_kets, - ) + results = _jited_loop_vmaped_state_sample_sweep( + target, num_qudits, radixes, locations, gates, untrys, + self.dist_tol, self.max_iters, self.beta, + num_starts, self.min_iters, self.diff_tol_r, + self.plateau_windows_size, self.overtrain_ratio, + training_states_kets, validation_states_kets, + ) + + final_untrys, training_costs, validation_costs, iteration_counts, \ + plateau_windows = results it = iteration_counts[0] untrys = final_untrys @@ -240,23 +241,31 @@ def multi_start_instantiate( f'Best start is {best_start}', ) elif it >= self.max_iters: - _logger.debug(f'Terminated {it}: iteration limit reached. c1 = {training_costs}') + _logger.debug( + f'Terminated {it}: iteration limit reached. c1 = ' + f'{training_costs}', + ) elif it > self.min_iters: - if all(validation_costs - training_costs > self.overtrain_ratio * training_costs): + val_to_train_diff = validation_costs - training_costs + if all( + val_to_train_diff > self.overtrain_ratio * training_costs, + ): _logger.debug( - f'Terminated: {it} overtraining detected in all multistarts', + f'Terminated: {it} overtraining detected in' + f' all multistarts', ) have_sufficient_states = False elif np.all(np.all(plateau_windows, axis=1)): _logger.debug( - f'Terminated: {it} plateau detected in all multistarts c1 = {training_costs}', + f'Terminated: {it} plateau detected in all' + f' multistarts c1 = {training_costs}', ) else: _logger.error( f'Terminated with no good reason after {it} iterations ' f'with c1s {training_costs}.', ) - + if should_double_the_training_size: amount_of_training_states *= 2 else: @@ -374,10 +383,10 @@ def _loop_vmaped_state_sample_sweep( gates: tuple[Gate, ...], untrys: Array, dist_tol: float, max_iters: int, beta: float, amount_of_starts: int, min_iters: int, - diff_tol_r:float, plateau_windows_size:int, + diff_tol_r: float, plateau_windows_size: int, overtrain_ratio: float, training_states_kets: Array, validation_states_kets: Array, -) -> tuple[Array, Array[float], Array[float], Array[int]]: +) -> tuple[Array, Array[float], Array[float], Array[int], Array[bool]]: # Calculate the bras for the validation and training states validation_states_bras = jax.vmap( @@ -417,10 +426,11 @@ def _loop_vmaped_state_sample_sweep( def should_continue( loop_var: tuple[ - Array, Array[float], Array[float], Array[int],Array[bool] + Array, Array[float], Array[float], Array[int], Array[bool], ], ) -> Array[bool]: - _, training_costs, validation_costs, iteration_counts, plateau_windows = loop_var + _, training_costs, validation_costs, \ + iteration_counts, plateau_windows = loop_var any_reached_required_tol = jnp.any( jax.vmap( @@ -431,12 +441,13 @@ def should_continue( reached_max_iteration = iteration_counts[0] > max_iters above_min_iteration = iteration_counts[0] > min_iters + val_to_train_diff = validation_costs - training_costs all_reached_over_training = jnp.all( - validation_costs - training_costs > overtrain_ratio * training_costs, + val_to_train_diff > overtrain_ratio * training_costs, ) - all_reached_plateau = jnp.all( - jnp.all(plateau_windows, axis=1) + all_reached_plateau = jnp.all( + jnp.all(plateau_windows, axis=1), ) return jnp.logical_not( @@ -448,8 +459,8 @@ def should_continue( above_min_iteration, jnp.logical_or( all_reached_over_training, - all_reached_plateau - ) + all_reached_plateau, + ), ), ), ), @@ -457,13 +468,14 @@ def should_continue( def _while_body_to_be_vmaped( loop_var: tuple[ - Array, Array[float], Array[float], Array[int], Array[bool] + Array, Array[float], Array[float], Array[int], Array[bool], ], ) -> tuple[ - Array, Array[float], Array[float], Array[int], + Array, Array[float], Array[float], Array[int], Array[bool], ]: - untrys, training_cost, validation_cost, iteration_count, plateau_window = loop_var + untrys, training_cost, validation_cost, iteration_count, \ + plateau_window = loop_var untrys_as_matrixes: list[UnitaryMatrixJax] = [] for gate_index, gate in enumerate(gates): @@ -485,11 +497,14 @@ def _while_body_to_be_vmaped( iteration_count += 1 have_detected_plateau_in_curr_iter = jnp.abs( - prev_training_cost - training_cost + prev_training_cost - training_cost, ) <= diff_tol_r * jnp.abs(training_cost) plateau_window = jnp.concatenate( - (jnp.array([have_detected_plateau_in_curr_iter]), plateau_window[:-1]), + ( + jnp.array([have_detected_plateau_in_curr_iter]), + plateau_window[:-1], + ), ) biggest_gate_size = max(gate.num_qudits for gate in gates) @@ -502,7 +517,7 @@ def _while_body_to_be_vmaped( return ( final_untrys_padded, training_cost, validation_cost, - iteration_count, plateau_window + iteration_count, plateau_window, ) while_body_vmaped = jax.vmap(_while_body_to_be_vmaped) @@ -512,7 +527,7 @@ def _while_body_to_be_vmaped( jnp.ones(amount_of_starts), # train_cost jnp.ones(amount_of_starts), # val_cost jnp.zeros(amount_of_starts, dtype=int), # iter_count - np.zeros((amount_of_starts, plateau_windows_size), dtype=bool) + np.zeros((amount_of_starts, plateau_windows_size), dtype=bool), ) if 'PRINT_LOSS_QFACTOR' in os.environ: @@ -520,18 +535,25 @@ def _while_body_to_be_vmaped( i = 1 while should_continue(loop_var): loop_var = while_body_vmaped(loop_var) - - untrys, training_costs, validation_costs, iteration_counts, plateau_windows = loop_var + + untrys, training_costs, validation_costs, iteration_counts, \ + plateau_windows = loop_var print(f'TRAINLOSS{i}:', training_costs) print(f'VALLOSS{i}:', validation_costs) i += 1 r = loop_var else: - r = jax.lax.while_loop(should_continue, while_body_vmaped, initial_loop_var) - - final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows = r + r = jax.lax.while_loop( + should_continue, while_body_vmaped, initial_loop_var, + ) - return final_untrys, training_costs, validation_costs, iteration_counts, plateau_windows + final_untrys, training_costs, validation_costs, iteration_counts, \ + plateau_windows = r + + return ( + final_untrys, training_costs, validation_costs, + iteration_counts, plateau_windows, + ) def state_sample_single_sweep( @@ -592,6 +614,6 @@ def calc_cost(A: RHSTensor, B0: LHSTensor, a: RHSTensor) -> float: else: _jited_loop_vmaped_state_sample_sweep = jax.jit( _loop_vmaped_state_sample_sweep, static_argnums=( - 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, ), ) From 5a10d0092ddd6ecf71d78359cff3dd66ecb800b6 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Wed, 25 Oct 2023 07:29:27 -0700 Subject: [PATCH 32/59] Adding params to the file --- examples/compare_state_sample_to_orig.py | 54 +++++++++++++++++------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index 99eb819..1e42d8b 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys import time from bqskit.ir.circuit import Circuit from bqskit.compiler import Compiler, CompilationTask @@ -9,11 +8,40 @@ from bqskitqfactorjax.qfactor_sample_jax import QFactorSampleJax from bqskitqfactorjax.qfactor_jax import QFactor_jax from bqskit.passes import ToVariablePass +from bqskit import enable_logging -dist_tol_requested = float(sys.argv[2]) -num_mutlistarts = 16 +enable_logging(verbose=True) -num_params_coeff = float(sys.argv[3]) + + +import argparse + +parser = argparse.ArgumentParser(description='Arguments for performance analysis') + +parser.add_argument('--input_qasm', type=str, required=True) +parser.add_argument('--multistarts', type=int, default=32) +parser.add_argument('--max_iters', type=int, default=300) +parser.add_argument('--dist_tol', type=float, default=1e-8) +parser.add_argument('--num_params_coef', type=int, default=1) +parser.add_argument('--exact_amount_of_sample_states', type=int) +parser.add_argument('--overtrain_relative_threshold', type=float, default=0.1) + + + +params = parser.parse_args() + + +print(params) + +file_name = params.input_qasm +dist_tol_requested = params.dist_tol +num_mutlistarts = params.multistarts +max_iters = params.max_iters + +num_params_coef = params.num_params_coef + +exact_amount_of_sample_states = params.exact_amount_of_sample_states +overtrain_relative_threshold = params.overtrain_relative_threshold instantiate_options = { @@ -48,25 +76,21 @@ dist_tol=dist_tol_requested, # Stopping criteria for distance - max_iters=2, # Maximum number of iterations - min_iters=1, # Minimum number of iterations + max_iters=max_iters, # Maximum number of iterations + min_iters=5, # Minimum number of iterations # Regularization parameter - [0.0 - 1.0] # Increase to overcome local minima at the price of longer compute beta=0.0, amount_of_validation_states=2, - num_params_coeff=num_params_coeff, # indicates the ratio between the sum of parameters in the circuits to the sample size. - overtrain_ratio=1 / 32, + num_params_coef=num_params_coef, # indicates the ratio between the sum of parameters in the circuits to the sample size. + overtrain_relative_threshold=overtrain_relative_threshold, + exact_amount_of_states_to_train_on = exact_amount_of_sample_states, ) -# file_name = 'heisenberg64_10q_block_100.qasm' -# file_name = 'heisenberg64_10q_block_036.qasm' -file_name = sys.argv[1] -# orig_10q_block_cir = Circuit.from_file('adder63_10q_block_47.qasm') -# orig_10q_block_cir = Circuit.from_file('adder63_10q_block_63.qasm') -print(f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coeff = }') +print(f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coef = }') orig_10q_block_cir = Circuit.from_file(f'{file_name}') @@ -86,7 +110,7 @@ sample_inst_time = time.perf_counter() - tic inst_sample_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) -print(f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coeff = }') +print(f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coef = }') # tic = time.perf_counter() # orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_gpu_instantiator) From 2ea075694b1baa3263f30e28518abaeacd20e59f Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 27 Oct 2023 14:07:29 -0700 Subject: [PATCH 33/59] Fixing the name of the pakcage --- examples/compare_state_sample_to_orig.py | 6 +++--- examples/toffoli_instantiation_using_sampling.py | 6 +++--- qfactorjax/qfactor_sample_jax.py | 14 +++++++------- qfactorjax/singlelegedtensor.py | 2 +- tests/test_single_leg_tensor.py | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index 1e42d8b..a8cc03e 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -5,8 +5,8 @@ from bqskit.compiler import Compiler, CompilationTask # from inst_pass import InstPass -from bqskitqfactorjax.qfactor_sample_jax import QFactorSampleJax -from bqskitqfactorjax.qfactor_jax import QFactor_jax +from qfactorjax.qfactor import QFactorJax +from qfactorjax.qfactor_sample_jax import QFactorSampleJax from bqskit.passes import ToVariablePass from bqskit import enable_logging @@ -49,7 +49,7 @@ } -qfactor_gpu_instantiator = QFactor_jax( +qfactor_gpu_instantiator = QFactorJax( dist_tol=dist_tol_requested, # Stopping criteria for distance diff --git a/examples/toffoli_instantiation_using_sampling.py b/examples/toffoli_instantiation_using_sampling.py index e598928..f886b47 100644 --- a/examples/toffoli_instantiation_using_sampling.py +++ b/examples/toffoli_instantiation_using_sampling.py @@ -11,11 +11,11 @@ from bqskit.ir.gates import VariableUnitaryGate from bqskit.qis.unitary import UnitaryMatrix -from bqskitqfactorjax.qfactor_sample_jax import QFactorSampleJax +from qfactorjax.qfactor_sample_jax import QFactorSampleJax def run_toffoli_instantiation(dist_tol_requested: float = 1e-10) -> float: - qfactr_gpu_instantiator = QFactorSampleJax( + qfactor_gpu_instantiator = QFactorSampleJax( dist_tol=dist_tol_requested, # Stopping criteria for distance @@ -56,7 +56,7 @@ def run_toffoli_instantiation(dist_tol_requested: float = 1e-10) -> float: circuit.instantiate( toffoli, multistarts=16, - method=qfactr_gpu_instantiator, + method=qfactor_gpu_instantiator, ) # Calculate and print final distance diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index b60659f..21b2db0 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -21,13 +21,13 @@ from jax import Array from scipy.stats import unitary_group -from bqskitqfactorjax.qfactor_jax import _apply_padding_and_flatten -from bqskitqfactorjax.qfactor_jax import _remove_padding_and_create_matrix -from bqskitqfactorjax.singlelegedtensor import LHSTensor -from bqskitqfactorjax.singlelegedtensor import RHSTensor -from bqskitqfactorjax.singlelegedtensor import SingleLegSideTensor -from bqskitqfactorjax.unitary_acc import VariableUnitaryGateAcc -from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax +from qfactorjax.qfactor import _apply_padding_and_flatten +from qfactorjax.qfactor import _remove_padding_and_create_matrix +from qfactorjax.singlelegedtensor import LHSTensor +from qfactorjax.singlelegedtensor import RHSTensor +from qfactorjax.singlelegedtensor import SingleLegSideTensor +from qfactorjax.unitary_acc import VariableUnitaryGateAcc +from qfactorjax.unitarymatrixjax import UnitaryMatrixJax if TYPE_CHECKING: from bqskit.ir.circuit import Circuit diff --git a/qfactorjax/singlelegedtensor.py b/qfactorjax/singlelegedtensor.py index 1cf7cda..4801ce7 100644 --- a/qfactorjax/singlelegedtensor.py +++ b/qfactorjax/singlelegedtensor.py @@ -7,7 +7,7 @@ from bqskit.ir import CircuitLocation from jax import Array -from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax +from qfactorjax.unitarymatrixjax import UnitaryMatrixJax T = TypeVar('T', bound='SingleLegSideTensor') diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py index efe302d..3bfdb61 100644 --- a/tests/test_single_leg_tensor.py +++ b/tests/test_single_leg_tensor.py @@ -7,10 +7,10 @@ import pytest from bqskit.ir.gates import CXGate from bqskit.ir.gates import HGate -from bqskitqfactorjax.singlelegedtensor import LHSTensor -from bqskitqfactorjax.singlelegedtensor import RHSTensor -from bqskitqfactorjax.singlelegedtensor import SingleLegSideTensor -from bqskitqfactorjax.unitarymatrixjax import UnitaryMatrixJax +from qfactorjax.singlelegedtensor import LHSTensor +from qfactorjax.singlelegedtensor import RHSTensor +from qfactorjax.singlelegedtensor import SingleLegSideTensor +from qfactorjax.unitarymatrixjax import UnitaryMatrixJax from scipy.stats import unitary_group From 14f798ad9a176901b6bce396a7f95f508f9e90d3 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 27 Oct 2023 14:10:30 -0700 Subject: [PATCH 34/59] fixing the exported name --- qfactorjax/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qfactorjax/__init__.py b/qfactorjax/__init__.py index bac6f89..1e9a2a2 100644 --- a/qfactorjax/__init__.py +++ b/qfactorjax/__init__.py @@ -1,7 +1,7 @@ from __future__ import annotations __all__ = [ - 'qfactor_jax', + 'qfactor', 'unitary_acc', 'unitarybuilderjax', 'unitarymatrixjax', From 32227ebd60d8137c0773952a7ceabd945382c357 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 27 Oct 2023 22:54:27 -0700 Subject: [PATCH 35/59] Using dims --- qfactorjax/qfactor_sample_jax.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 21b2db0..790ca09 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -52,7 +52,7 @@ def __init__( amount_of_validation_states: int = 2, num_params_coef: float = 1.0, overtrain_relative_threshold: float = 0.1, - diff_tol_r: float = 1e-4, # Relative criteria for distance change + diff_tol_r: float = 1e-2, # Relative criteria for distance change plateau_windows_size: int = 6, exact_amount_of_states_to_train_on: int | None = None, ): @@ -128,18 +128,23 @@ def multi_start_instantiate( circuit = circuit.copy() - # A very ugly casting + gates_list = [] for op in circuit: - g = op.gate - if isinstance(g, VariableUnitaryGate): - g.__class__ = VariableUnitaryGateAcc + if isinstance(op.gate, VariableUnitaryGate): + new_gate = VariableUnitaryGateAcc( + op.gate.num_qudits, + op.gate.radixes, + ) + gates_list.append(new_gate) + else: + gates_list.append(op.gate) target = UnitaryMatrixJax(self.check_target(target)) - locations = tuple([op.location for op in circuit]) - gates = tuple([op.gate for op in circuit]) - biggest_gate_size = max(gate.num_qudits for gate in gates) radixes = target.radixes num_qudits = target.num_qudits + locations = tuple([op.location for op in circuit]) + gates = tuple(gates_list) + biggest_gate_dim = max(g.dim for g in circuit.gate_set) # Initial number of states to use can b if self.exact_amount_of_states_to_train_on is None: @@ -180,7 +185,7 @@ def multi_start_instantiate( untrys.append([ _apply_padding_and_flatten( - pre_padd, gate, biggest_gate_size, + pre_padd, gate, biggest_gate_dim, ) for pre_padd in pre_padding_untrys ]) @@ -209,7 +214,7 @@ def multi_start_instantiate( untrys.append([ _apply_padding_and_flatten( - pre_padd, gate, biggest_gate_size, + pre_padd, gate, biggest_gate_dim, ) for pre_padd in pre_padding_untrys ]) @@ -507,11 +512,11 @@ def _while_body_to_be_vmaped( ), ) - biggest_gate_size = max(gate.num_qudits for gate in gates) + biggest_gate_dim = max(g.dim for g in gates) final_untrys_padded = jnp.array([ _apply_padding_and_flatten( untry.numpy.flatten( - ), gate, biggest_gate_size, + ), gate, biggest_gate_dim, ) for untry, gate in zip(untrys_as_matrixes, gates) ]) From 2ddef1aa59acb561cdcde587e78928faa039f0bf Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Sun, 12 Nov 2023 08:00:50 -0800 Subject: [PATCH 36/59] Update default params --- qfactorjax/qfactor_sample_jax.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 790ca09..ef67118 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -45,14 +45,14 @@ class QFactorSampleJax(Instantiater): def __init__( self, - dist_tol: float = 1e-10, + dist_tol: float = 1e-8, max_iters: int = 100000, - min_iters: int = 1000, + min_iters: int = 2, beta: float = 0.0, amount_of_validation_states: int = 2, num_params_coef: float = 1.0, overtrain_relative_threshold: float = 0.1, - diff_tol_r: float = 1e-2, # Relative criteria for distance change + diff_tol_r: float = 1e-4, # Relative criteria for distance change plateau_windows_size: int = 6, exact_amount_of_states_to_train_on: int | None = None, ): From 3ce906d4134ed6ff1f28bec37c7bad63f0c67624 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Fri, 8 Dec 2023 11:58:06 -0800 Subject: [PATCH 37/59] Saving thr amount the training states needed for instantiation --- qfactorjax/qfactor_sample_jax.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index ef67118..cbb343b 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -78,6 +78,8 @@ def __init__( self.plateau_windows_size = plateau_windows_size self.exact_amount_of_states_to_train_on =\ exact_amount_of_states_to_train_on + + self.amount_of_training_states_used_last_iter = 0 def instantiate( self, @@ -270,7 +272,7 @@ def multi_start_instantiate( f'Terminated with no good reason after {it} iterations ' f'with c1s {training_costs}.', ) - + self.amount_of_training_states_used_last_iter = amount_of_training_states if should_double_the_training_size: amount_of_training_states *= 2 else: From 16e4ea538dbba2ac2f0e8eebc553ba7095bf7e8d Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 18 Dec 2023 10:48:08 -0800 Subject: [PATCH 38/59] Changing the name of the logger, so the runtime will FWD it --- qfactorjax/qfactor.py | 2 +- qfactorjax/qfactor_sample_jax.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qfactorjax/qfactor.py b/qfactorjax/qfactor.py index 5b80f00..acf6509 100644 --- a/qfactorjax/qfactor.py +++ b/qfactorjax/qfactor.py @@ -30,7 +30,7 @@ from bqskit.qis.state.system import StateSystemLike from bqskit.qis.unitary.unitarymatrix import UnitaryLike -_logger = logging.getLogger(__name__) +_logger = logging.getLogger('bqskit.instant.qf-jax') jax.config.update('jax_enable_x64', True) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index cbb343b..709f7f9 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -35,7 +35,7 @@ from bqskit.qis.state.system import StateSystemLike from bqskit.qis.unitary.unitarymatrix import UnitaryLike -_logger = logging.getLogger(__name__) +_logger = logging.getLogger('bqskit.instant.qf-sample-jax') jax.config.update('jax_enable_x64', True) From e90889125df92bbd901ac0579c6ddba25b1d5956 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 18 Dec 2023 10:48:59 -0800 Subject: [PATCH 39/59] Stopping the instantiation if trying to use more 2^num_qudits states --- qfactorjax/qfactor_sample_jax.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 709f7f9..00f29e8 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -226,7 +226,11 @@ def multi_start_instantiate( amount_of_training_states, int(np.prod(radixes)), ) - results = _jited_loop_vmaped_state_sample_sweep( + if 2**num_qudits < amount_of_training_states: + _logger.error(f"Aborted, was trying to use {amount_of_training_states = } while {num_qudits =}") + best_start = 0 #need to return some values + break + target, num_qudits, radixes, locations, gates, untrys, self.dist_tol, self.max_iters, self.beta, num_starts, self.min_iters, self.diff_tol_r, From 770a2ead22dd9015f688dcafea2856fdb9938172 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 19 Dec 2023 12:06:03 -0800 Subject: [PATCH 40/59] Pre-commit fixes --- tests/test_examples.py | 4 +++- tests/test_single_leg_tensor.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index 0bc5fdf..dc0d483 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -7,13 +7,15 @@ from examples.gate_deletion_syth import run_gate_del_flow_example from examples.toffoli_instantiation import run_toffoli_instantiation -from examples.toffoli_instantiation_using_sampling import run_toffoli_instantiation as run_toffoli_instantiation_using_sampling +from examples.toffoli_instantiation_using_sampling import\ + run_toffoli_instantiation as run_toffoli_instantiation_using_sampling def test_toffoli_instantiation() -> None: distance = run_toffoli_instantiation() assert distance <= 1e-10 + def test_toffoli_instantiation_using_sampling() -> None: distance = run_toffoli_instantiation_using_sampling() assert distance <= 1e-10 diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py index 3bfdb61..ac6d801 100644 --- a/tests/test_single_leg_tensor.py +++ b/tests/test_single_leg_tensor.py @@ -7,11 +7,12 @@ import pytest from bqskit.ir.gates import CXGate from bqskit.ir.gates import HGate +from scipy.stats import unitary_group + from qfactorjax.singlelegedtensor import LHSTensor from qfactorjax.singlelegedtensor import RHSTensor from qfactorjax.singlelegedtensor import SingleLegSideTensor from qfactorjax.unitarymatrixjax import UnitaryMatrixJax -from scipy.stats import unitary_group @pytest.mark.parametrize( From d4559779dc59ce6a11abdb1b23478f5b72682f3b Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 19 Dec 2023 12:07:42 -0800 Subject: [PATCH 41/59] Change print to log debug --- qfactorjax/qfactor_sample_jax.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 00f29e8..4e80caa 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -549,8 +549,8 @@ def _while_body_to_be_vmaped( untrys, training_costs, validation_costs, iteration_counts, \ plateau_windows = loop_var - print(f'TRAINLOSS{i}:', training_costs) - print(f'VALLOSS{i}:', validation_costs) + _logger.debug(f'TRAINLOSS{i}: {training_costs}') + _logger.debug(f'VALLOSS{i}: {validation_costs}') i += 1 r = loop_var else: From 260a8ba4b696c74dcfbe2ba0473f11a629349c8a Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 19 Dec 2023 12:10:10 -0800 Subject: [PATCH 42/59] 1. Recursively split by 2 the num_starts when OMM 2. Cache the number of training states needed according to a hash of the target unitary --- qfactorjax/qfactor_sample_jax.py | 157 +++++++++++++++++++++++++------ 1 file changed, 127 insertions(+), 30 deletions(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 4e80caa..018af8b 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -2,6 +2,7 @@ import logging import os +from enum import Enum from typing import Sequence from typing import TYPE_CHECKING @@ -19,6 +20,7 @@ from bqskit.qis.state import StateSystem from bqskit.qis.state import StateVector from jax import Array +from jax._src.lib import xla_extension as xe from scipy.stats import unitary_group from qfactorjax.qfactor import _apply_padding_and_flatten @@ -41,6 +43,14 @@ jax.config.update('jax_enable_x64', True) +class TermCondition(Enum): + UNKNOWN = 0 + REACHED_TARGET = 1 + EXCEEDED_MAX_ITER = 2 + PLATEAU_DETECTED = 3 + EXCEEDED_TRAINING_SET_SIZE = 4 + + class QFactorSampleJax(Instantiater): def __init__( @@ -78,8 +88,8 @@ def __init__( self.plateau_windows_size = plateau_windows_size self.exact_amount_of_states_to_train_on =\ exact_amount_of_states_to_train_on - - self.amount_of_training_states_used_last_iter = 0 + + self.targets_training_set_size_cache: dict[int, int] = {} def instantiate( self, @@ -141,6 +151,7 @@ def multi_start_instantiate( else: gates_list.append(op.gate) + target_hash = target.__hash__() target = UnitaryMatrixJax(self.check_target(target)) radixes = target.radixes num_qudits = target.num_qudits @@ -148,8 +159,10 @@ def multi_start_instantiate( gates = tuple(gates_list) biggest_gate_dim = max(g.dim for g in circuit.gate_set) - # Initial number of states to use can b - if self.exact_amount_of_states_to_train_on is None: + if target_hash in self.targets_training_set_size_cache: + initial_amount_of_training_states =\ + self.targets_training_set_size_cache[target_hash] + elif self.exact_amount_of_states_to_train_on is None: amount_of_params_in_circuit = 0 for g in gates: amount_of_params_in_circuit += g.num_params @@ -160,6 +173,15 @@ def multi_start_instantiate( initial_amount_of_training_states =\ self.exact_amount_of_states_to_train_on + if np.prod(radixes) < initial_amount_of_training_states: + _logger.warning( + f'Requested to use ' + f'{initial_amount_of_training_states} training ' + 'states, while the prod of the radixes is ' + f'{np.prod(radixes)}. This algorithm shines when we have ' + f'much less training states than 2^prod(radixes)', + ) + amount_of_training_states = initial_amount_of_training_states validation_states_kets = self.generate_random_states( @@ -193,10 +215,9 @@ def multi_start_instantiate( untrys = jnp.array(np.stack(untrys, axis=1)) - have_sufficient_states = False + term_condition = None should_double_the_training_size = True - while not have_sufficient_states: - + while term_condition is None: if not generate_untrys_only_once: untrys = [] @@ -226,16 +247,9 @@ def multi_start_instantiate( amount_of_training_states, int(np.prod(radixes)), ) - if 2**num_qudits < amount_of_training_states: - _logger.error(f"Aborted, was trying to use {amount_of_training_states = } while {num_qudits =}") - best_start = 0 #need to return some values - break - - target, num_qudits, radixes, locations, gates, untrys, - self.dist_tol, self.max_iters, self.beta, - num_starts, self.min_iters, self.diff_tol_r, - self.plateau_windows_size, self.overtrain_ratio, - training_states_kets, validation_states_kets, + results = self.safe_call_jited_vmaped_state_sample_sweep( + target, num_starts, radixes, num_qudits, locations, gates, + validation_states_kets, untrys, training_states_kets, ) final_untrys, training_costs, validation_costs, iteration_counts, \ @@ -245,42 +259,68 @@ def multi_start_instantiate( untrys = final_untrys best_start = jnp.argmin(training_costs) - have_sufficient_states = True if any(training_costs < self.dist_tol): _logger.debug( f'Terminated: {it} c1 = {training_costs} <= dist_tol.\n' f'Best start is {best_start}', ) + term_condition = TermCondition.REACHED_TARGET elif it >= self.max_iters: _logger.debug( f'Terminated {it}: iteration limit reached. c1 = ' f'{training_costs}', ) + term_condition = TermCondition.EXCEEDED_MAX_ITER elif it > self.min_iters: val_to_train_diff = validation_costs - training_costs - if all( + + if np.all(np.all(plateau_windows, axis=1)): + _logger.debug( + f'Terminated: {it} plateau detected in all' + f' multistarts c1 = {training_costs}', + ) + term_condition = TermCondition.PLATEAU_DETECTED + + elif all( val_to_train_diff > self.overtrain_ratio * training_costs, ): _logger.debug( f'Terminated: {it} overtraining detected in' f' all multistarts', ) - have_sufficient_states = False - elif np.all(np.all(plateau_windows, axis=1)): - _logger.debug( - f'Terminated: {it} plateau detected in all' - f' multistarts c1 = {training_costs}', - ) + + else: + term_condition = TermCondition.UNKNOWN else: + term_condition = TermCondition.UNKNOWN + + if term_condition == TermCondition.UNKNOWN: _logger.error( f'Terminated with no good reason after {it} iterations ' f'with c1s {training_costs}.', ) - self.amount_of_training_states_used_last_iter = amount_of_training_states - if should_double_the_training_size: - amount_of_training_states *= 2 - else: - amount_of_training_states += initial_amount_of_training_states + + if ( + term_condition == TermCondition.REACHED_TARGET + or term_condition == TermCondition.PLATEAU_DETECTED + or term_condition == TermCondition.EXCEEDED_MAX_ITER + ): + self.targets_training_set_size_cache[target_hash] =\ + amount_of_training_states + + if term_condition is None: + if should_double_the_training_size: + amount_of_training_states *= 2 + else: + amount_of_training_states +=\ + initial_amount_of_training_states + + if amount_of_training_states > np.prod(radixes): + term_condition = TermCondition.EXCEEDED_TRAINING_SET_SIZE + _logger.debug( + 'Stopping as we reached the max number of' + ' training states', + ) params: list[Sequence[float]] = [] for untry, gate in zip(untrys[best_start], gates): @@ -295,6 +335,63 @@ def multi_start_instantiate( return np.array(params) + def safe_call_jited_vmaped_state_sample_sweep( + self, + target: UnitaryMatrixJax, + num_starts: int, + radixes: tuple[int, ...], + num_qudits: int, + locations: tuple[CircuitLocation, ...], + gates: tuple[Gate, ...], + validation_states_kets: Array, + untrys: Array, + training_states_kets: Array, + ) -> tuple[Array, Array[float], Array[float], Array[int], Array[bool]]: + + try: + results = _jited_loop_vmaped_state_sample_sweep( + target, num_qudits, radixes, locations, gates, untrys, + self.dist_tol, self.max_iters, self.beta, + num_starts, self.min_iters, self.diff_tol_r, + self.plateau_windows_size, self.overtrain_ratio, + training_states_kets, validation_states_kets, + ) + + except xe.XlaRuntimeError as e: + + if num_starts == 1: + _logger.error( + f'Got a runtime error {e}, while {num_starts = } ,exiting', + ) + raise e + + _logger.debug( + f'Got a runtime error {e} will try re-run with half the starts', + ) + + mid_point = num_starts // 2 + first_half_untrys = untrys[:mid_point] + second_half_untrys = untrys[mid_point:] + + results1 = self.safe_call_jited_vmaped_state_sample_sweep( + target, mid_point, radixes, num_qudits, locations, gates, + validation_states_kets, first_half_untrys, + training_states_kets, + ) + + results2 = self.safe_call_jited_vmaped_state_sample_sweep( + target, num_starts - mid_point, radixes, num_qudits, locations, + gates, validation_states_kets, second_half_untrys, + training_states_kets, + ) + + results = tuple( + jnp.concatenate((results1[i], results2[i])) + for i in range(5) + ) + + return results + @staticmethod def get_method_name() -> str: """Return the name of this method.""" From c3b224c5b7ca352d50db28b396cf20dad02520a7 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 19 Dec 2023 12:14:24 -0800 Subject: [PATCH 43/59] pre-commit fixes --- examples/compare_state_sample_to_orig.py | 76 ++++++++++++------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index a8cc03e..8a1e064 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -1,35 +1,35 @@ from __future__ import annotations +import argparse import time + +from bqskit import enable_logging +from bqskit.compiler import CompilationTask +from bqskit.compiler import Compiler from bqskit.ir.circuit import Circuit -from bqskit.compiler import Compiler, CompilationTask -# from inst_pass import InstPass +from bqskit.passes import ToVariablePass from qfactorjax.qfactor import QFactorJax from qfactorjax.qfactor_sample_jax import QFactorSampleJax -from bqskit.passes import ToVariablePass -from bqskit import enable_logging enable_logging(verbose=True) - -import argparse - -parser = argparse.ArgumentParser(description='Arguments for performance analysis') +parser = argparse.ArgumentParser( + description='Arguments for performance analysis', +) parser.add_argument('--input_qasm', type=str, required=True) parser.add_argument('--multistarts', type=int, default=32) -parser.add_argument('--max_iters', type=int, default=300) -parser.add_argument('--dist_tol', type=float, default=1e-8) -parser.add_argument('--num_params_coef', type=int, default=1) +parser.add_argument('--max_iters', type=int, default=300) +parser.add_argument('--dist_tol', type=float, default=1e-8) +parser.add_argument('--num_params_coef', type=int, default=1) parser.add_argument('--exact_amount_of_sample_states', type=int) -parser.add_argument('--overtrain_relative_threshold', type=float, default=0.1) - +parser.add_argument('--overtrain_relative_threshold', type=float, default=0.1) params = parser.parse_args() - + print(params) @@ -45,8 +45,8 @@ instantiate_options = { - 'multistarts': num_mutlistarts, - } + 'multistarts': num_mutlistarts, +} qfactor_gpu_instantiator = QFactorJax( @@ -84,13 +84,16 @@ beta=0.0, amount_of_validation_states=2, - num_params_coef=num_params_coef, # indicates the ratio between the sum of parameters in the circuits to the sample size. + # indicates the ratio between the sum of parameters in the circuits to the sample size. + num_params_coef=num_params_coef, overtrain_relative_threshold=overtrain_relative_threshold, - exact_amount_of_states_to_train_on = exact_amount_of_sample_states, + exact_amount_of_states_to_train_on=exact_amount_of_sample_states, ) -print(f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coef = }') +print( + f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coef = }', +) orig_10q_block_cir = Circuit.from_file(f'{file_name}') @@ -103,28 +106,25 @@ tic = time.perf_counter() target = orig_10q_block_cir_vu.get_unitary() time_to_simulate_circ = time.perf_counter() - tic -print(f"Time to simulate was {time_to_simulate_circ}") +print(f'Time to simulate was {time_to_simulate_circ}') tic = time.perf_counter() -orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactor_sample_gpu_instantiator) +orig_10q_block_cir_vu.instantiate( + target, multistarts=num_mutlistarts, method=qfactor_sample_gpu_instantiator, +) sample_inst_time = time.perf_counter() - tic -inst_sample_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) - -print(f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coef = }') +inst_sample_dist_from_target = orig_10q_block_cir_vu.get_unitary( +).get_distance_from(target, 1) -# tic = time.perf_counter() -# orig_10q_block_cir_vu.instantiate(target, multistarts=num_mutlistarts, method=qfactr_gpu_instantiator) -# full_inst_time = time.perf_counter() - tic -# inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) - -# print(f'full method {full_inst_time = } {inst_dist_from_target = }') +print( + f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coef = }', +) -# with Compiler(num_workers=num_mutlistarts+1) as compiler: -# task = CompilationTask(orig_10q_block_cir, [InstPass(instantiate_options, target)]) -# tic = time.perf_counter() -# task_id = compiler.submit(task) -# circ = compiler.result(task_id) # type: ignore -# ceres_inst_time = time.perf_counter() - tic -# ceres_inst_dist_from_target = circ.get_unitary().get_distance_from(target, 1) +tic = time.perf_counter() +orig_10q_block_cir_vu.instantiate( + target, multistarts=num_mutlistarts, method=qfactor_gpu_instantiator, +) +full_inst_time = time.perf_counter() - tic +inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) -# print(f'CERES inst {ceres_inst_time = } {ceres_inst_dist_from_target = }') +print(f'full method {full_inst_time = } {inst_dist_from_target = }') From 256f863b4a343f38fbb0989afa90beb970589e5b Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Thu, 15 Feb 2024 14:14:24 -0800 Subject: [PATCH 44/59] Adding some doc --- qfactorjax/qfactor_sample_jax.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 018af8b..20c0eef 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -347,6 +347,12 @@ def safe_call_jited_vmaped_state_sample_sweep( untrys: Array, training_states_kets: Array, ) -> tuple[Array, Array[float], Array[float], Array[int], Array[bool]]: + """ + We couldn't find a way to check if we are going to allocate more than + the GPU memory, so we created this "safe" function that calls + qfactor-sample and then if OOM exception is caught it recursively + calls qfactor-sample with half the multistarts + """ try: results = _jited_loop_vmaped_state_sample_sweep( From 34f4df084654ab94a79081cd48b489cefddc2bc8 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 1 Jul 2024 14:56:27 -0700 Subject: [PATCH 45/59] Updating the references and year --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 729c0e6..f1ac163 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# QFactor implementation on GPUs using JAX -`bqskit-qfactor-jax` is a Python package that implements circuit instantiation with [QFactor](https://arxiv.org/abs/2306.08152) on GPUs to accelerate [BQSKit](https://github.com/bqskit/bqskit). It uses [JAX](https://jax.readthedocs.io/en/latest/index.html) as an abstraction layer of the GPUs, seamlessly utilizing JIT compilation and GPU parallelism. +# QFactor and QFactor-Sample implementations on GPUs using JAX +`bqskit-qfactor-jax` is a Python package that implements circuit instantiation using the [QFactor](https://ieeexplore.ieee.org/abstract/document/10313638) and [QFactor-Sample](https://arxiv.org/abs/2405.12866) algorithms on GPUs to accelerate [BQSKit](https://github.com/bqskit/bqskit). It uses [JAX](https://jax.readthedocs.io/en/latest/index.html) as an abstraction layer of the GPUs, seamlessly utilizing JIT compilation and GPU parallelism. ## Installation `bqskit-qfactor-jax` is available for Python 3.8+ on Linux. @@ -28,7 +28,11 @@ echo quit | nvidia-cuda-mps-control ``` # References -Kukliansky, Alon, et al. "QFactor:A Domain-Specific Optimizer for Quantum Circuit Instantiation." arXiv preprint [arXiv:2306.08152](https://arxiv.org/abs/2306.08152) (2023). +If you are using QFactor-JAX please cite: +Kukliansky, Alon, et al. "QFactor: A Domain-Specific Optimizer for Quantum Circuit Instantiation." 2023 IEEE International Conference on Quantum Computing and Engineering (QCE). Vol. 1. IEEE, 2023. [Link](https://ieeexplore.ieee.org/abstract/document/10313638). + +If you are using QFactor-Sample please cite: +Kukliansky, Alon, et al. "Leveraging Quantum Machine Learning Generalization to Significantly Speed-up Quantum Compilation" arXiv preprint [arXiv:2405.12866](https://arxiv.org/abs/2405.12866) (2024). ## License The software in this repository is licensed under a **BSD free software @@ -39,5 +43,5 @@ for more information. ## Copyright -Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2023, +Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2024, U.S. Federal Government and the Government of Israel. All rights reserved. From dabb9dda5fc48809ab1f7d11785824fbd325a8f9 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 1 Jul 2024 15:18:30 -0700 Subject: [PATCH 46/59] Ignoring a type error, this needs to be fixed... --- qfactorjax/qfactor_sample_jax.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/qfactorjax/qfactor_sample_jax.py b/qfactorjax/qfactor_sample_jax.py index 20c0eef..1705fc4 100644 --- a/qfactorjax/qfactor_sample_jax.py +++ b/qfactorjax/qfactor_sample_jax.py @@ -347,12 +347,10 @@ def safe_call_jited_vmaped_state_sample_sweep( untrys: Array, training_states_kets: Array, ) -> tuple[Array, Array[float], Array[float], Array[int], Array[bool]]: - """ - We couldn't find a way to check if we are going to allocate more than - the GPU memory, so we created this "safe" function that calls - qfactor-sample and then if OOM exception is caught it recursively - calls qfactor-sample with half the multistarts - """ + """We couldn't find a way to check if we are going to allocate more than + the GPU memory, so we created this "safe" function that calls qfactor- + sample and then if OOM exception is caught it recursively calls qfactor- + sample with half the multistarts.""" try: results = _jited_loop_vmaped_state_sample_sweep( @@ -391,10 +389,11 @@ def safe_call_jited_vmaped_state_sample_sweep( training_states_kets, ) + # TODO: Fix the typing ignore here results = tuple( jnp.concatenate((results1[i], results2[i])) for i in range(5) - ) + ) # type: ignore return results From cef123ab37be8895fcea1ab2d25509314f5314e5 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 1 Jul 2024 15:18:44 -0700 Subject: [PATCH 47/59] pro-commit fix --- examples/gate_deletion_syth.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/gate_deletion_syth.py b/examples/gate_deletion_syth.py index 4d9c785..23af2c6 100644 --- a/examples/gate_deletion_syth.py +++ b/examples/gate_deletion_syth.py @@ -7,6 +7,7 @@ from timeit import default_timer as timer from bqskit import Circuit +from bqskit import enable_logging from bqskit.compiler import Compiler from bqskit.passes import ForEachBlockPass from bqskit.passes import QuickPartitioner @@ -18,6 +19,9 @@ from qfactorjax.qfactor import QFactorJax +enable_logging() + + def run_gate_del_flow_example( amount_of_workers: int = 10, ) -> tuple[Circuit, Circuit, float]: @@ -102,7 +106,9 @@ def run_gate_del_flow_example( if __name__ == '__main__': - in_circuit, out_circuit, run_time = run_gate_del_flow_example() + in_circuit, out_circuit, run_time = run_gate_del_flow_example( + amount_of_workers=1, + ) print( f'Partitioning + Synthesis took {run_time}' From 076bc7b6dbe43f02b4e87c360d4a7c0f2cd8891f Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Mon, 1 Jul 2024 15:29:48 -0700 Subject: [PATCH 48/59] Enabling 64bit to have good accuracy --- tests/test_single_leg_tensor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_single_leg_tensor.py b/tests/test_single_leg_tensor.py index ac6d801..80c4f7d 100644 --- a/tests/test_single_leg_tensor.py +++ b/tests/test_single_leg_tensor.py @@ -3,6 +3,7 @@ from random import randint from random import sample +import jax import jax.numpy as jnp import pytest from bqskit.ir.gates import CXGate @@ -15,6 +16,9 @@ from qfactorjax.unitarymatrixjax import UnitaryMatrixJax +jax.config.update('jax_enable_x64', True) + + @pytest.mark.parametrize( 'num_qubits, N', [(randint(2, 7), randint(3, 10)) for _ in range(6)], From 558a074c7027a491f92ee091caf0979a54b4a0b3 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:32:47 -0700 Subject: [PATCH 49/59] Updating the qasms used for the reinst example --- examples/adder63_10q_block_28.qasm | 87 ++++ examples/adder63_10q_block_47.qasm | 114 ----- examples/adder63_10q_block_63.qasm | 112 ----- examples/compare_state_sample_to_orig.py | 26 +- examples/heisenberg64_10q_block_036.qasm | 108 ----- examples/heisenberg64_10q_block_100.qasm | 91 ---- examples/heisenberg64_10q_block_104.qasm | 57 +++ examples/shor26_10q_block_051.qasm | 341 -------------- examples/shor26_10q_block_134.qasm | 537 ----------------------- examples/vqe12_10q_block145.qasm | 60 +++ 10 files changed, 222 insertions(+), 1311 deletions(-) create mode 100644 examples/adder63_10q_block_28.qasm delete mode 100644 examples/adder63_10q_block_47.qasm delete mode 100644 examples/adder63_10q_block_63.qasm delete mode 100644 examples/heisenberg64_10q_block_036.qasm delete mode 100644 examples/heisenberg64_10q_block_100.qasm create mode 100644 examples/heisenberg64_10q_block_104.qasm delete mode 100644 examples/shor26_10q_block_051.qasm delete mode 100644 examples/shor26_10q_block_134.qasm create mode 100644 examples/vqe12_10q_block145.qasm diff --git a/examples/adder63_10q_block_28.qasm b/examples/adder63_10q_block_28.qasm new file mode 100644 index 0000000..92c612c --- /dev/null +++ b/examples/adder63_10q_block_28.qasm @@ -0,0 +1,87 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[7], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[7], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[7], q[9]; +cx q[5], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[5], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[5], q[7]; +cx q[4], q[5]; +cx q[7], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(0.0, 0.0, 0.7853981633974483) q[7]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, 0.0, 5.497787143782138) q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +cx q[2], q[4]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, 6.283185307179586) q[6]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.7853981633974483) q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[0], q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[7], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +cx q[0], q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +cx q[7], q[8]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +cx q[3], q[4]; +cx q[7], q[9]; +cx q[0], q[2]; +cx q[1], q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, 0.0, -3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +cx q[6], q[7]; +u3(0.0, 0.0, 7.0685834705770345) q[9]; +cx q[1], q[3]; +u3(1.5707963267948966, 2.356194490192345, -3.141592653589793) q[6]; +u3(1.5707963267948966, -2.356194490192345, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +cx q[7], q[9]; +cx q[1], q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; +cx q[7], q[9]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; +cx q[7], q[9]; +cx q[6], q[7]; +u3(0.0, 0.0, 5.497787143782138) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; diff --git a/examples/adder63_10q_block_47.qasm b/examples/adder63_10q_block_47.qasm deleted file mode 100644 index 1aa2e1f..0000000 --- a/examples/adder63_10q_block_47.qasm +++ /dev/null @@ -1,114 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[6], q[7]; -cx q[3], q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[6], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.9269908169872414) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[3], q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -cx q[3], q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -cx q[3], q[4]; -cx q[3], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -cx q[4], q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[5]; -cx q[8], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -cx q[4], q[5]; -u3(0.0, 0.0, 5.497787143782138) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[3], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[9]; -u3(1.5707963267948966, 0.0, 3.9269908169872414) q[8]; -cx q[8], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[8], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[8], q[9]; -cx q[3], q[8]; -cx q[4], q[9]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(0.0, 0.0, 5.497787143782138) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[3], q[8]; -cx q[4], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[4], q[9]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[8], q[9]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[8], q[9]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[2], q[5]; -cx q[8], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -cx q[2], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[2], q[5]; -cx q[1], q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -cx q[1], q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -cx q[1], q[2]; -cx q[0], q[1]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -cx q[0], q[1]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -cx q[0], q[1]; diff --git a/examples/adder63_10q_block_63.qasm b/examples/adder63_10q_block_63.qasm deleted file mode 100644 index 9ceb441..0000000 --- a/examples/adder63_10q_block_63.qasm +++ /dev/null @@ -1,112 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -cx q[2], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[2], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[2], q[6]; -cx q[0], q[2]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[0], q[2]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -cx q[0], q[2]; -cx q[5], q[6]; -cx q[0], q[1]; -u3(1.5707963267948966, -1.5707963267948966, -3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -cx q[4], q[5]; -cx q[0], q[1]; -u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, -4.71238898038469) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -cx q[4], q[5]; -cx q[0], q[1]; -u3(1.5707963267948966, 3.9269908169872414, 0.0) q[4]; -cx q[3], q[4]; -u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[5]; -u3(1.5707963267948966, -3.141592653589793, -1.5707963267948966) q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, -3.141592653589793, 5.497787143782138) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[3], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[5]; -u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, -4.71238898038469) q[4]; -cx q[3], q[4]; -u3(0.0, 0.0, 2.356194490192345) q[3]; -u3(1.5707963267948966, 3.141592653589793, -1.5707963267948966) q[4]; -cx q[4], q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -u3(0.0, 0.0, 5.497787143782138) q[5]; -cx q[4], q[5]; -cx q[3], q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[3], q[4]; -cx q[5], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -cx q[3], q[4]; -u3(0.0, 0.0, 4.71238898038469) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -cx q[4], q[5]; -u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, -4.71238898038469) q[5]; -cx q[4], q[5]; -u3(1.5707963267948966, 1.5707963267948966, 1.5707963267948966) q[4]; -u3(1.5707963267948966, 0.7853981633974483, -3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -cx q[5], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -cx q[4], q[5]; -u3(0.0, 0.0, 4.71238898038469) q[8]; -u3(1.5707963267948966, 0.0, 7.0685834705770345) q[4]; -u3(3.141592653589793, 1.8237544, 7.3215416) q[5]; -cx q[5], q[8]; -u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, -4.71238898038469) q[8]; -cx q[5], q[8]; -u3(1.5707963267948966, 1.5707963267948966, 3.141592653589793) q[5]; -cx q[4], q[5]; -u3(2.356194490192345, 4.71238898038469, -1.5707963267948966) q[8]; -u3(1.5707963267948966, 2.356194490192345, -3.141592653589793) q[4]; -cx q[8], q[9]; -cx q[3], q[4]; -u3(1.5707963267948966, -2.356194490192345, 3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -cx q[8], q[9]; -cx q[3], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; -cx q[8], q[9]; -cx q[3], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; -cx q[3], q[7]; diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index 8a1e064..b450d7f 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -16,12 +16,16 @@ parser = argparse.ArgumentParser( - description='Arguments for performance analysis', + description='Comparing the re-instantiation run time of QFactor-JAX and ' + 'QFactor-Sample-JAX. Running on adder63_10q_block_28.qasm the ' + 'difference is X4, and for heisenberg64_10q_block_104.qasm ' + 'the difference is X10 and QFactor-JAX doesn\'t find a solution. ' + 'For vqe12_10q_block145.qasm the difference is X34.', ) parser.add_argument('--input_qasm', type=str, required=True) parser.add_argument('--multistarts', type=int, default=32) -parser.add_argument('--max_iters', type=int, default=300) +parser.add_argument('--max_iters', type=int, default=6000) parser.add_argument('--dist_tol', type=float, default=1e-8) parser.add_argument('--num_params_coef', type=int, default=1) parser.add_argument('--exact_amount_of_sample_states', type=int) @@ -77,14 +81,16 @@ dist_tol=dist_tol_requested, # Stopping criteria for distance max_iters=max_iters, # Maximum number of iterations - min_iters=5, # Minimum number of iterations + min_iters=6, # Minimum number of iterations # Regularization parameter - [0.0 - 1.0] # Increase to overcome local minima at the price of longer compute beta=0.0, amount_of_validation_states=2, - # indicates the ratio between the sum of parameters in the circuits to the sample size. + # indicates the ratio between the sum of parameters in the circuits to the + # sample size. + diff_tol_r=1e-4, num_params_coef=num_params_coef, overtrain_relative_threshold=overtrain_relative_threshold, exact_amount_of_states_to_train_on=exact_amount_of_sample_states, @@ -92,7 +98,8 @@ print( - f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = } {num_params_coef = }', + f'Will use {file_name} {dist_tol_requested = } {num_mutlistarts = }' + f' {num_params_coef = }', ) orig_10q_block_cir = Circuit.from_file(f'{file_name}') @@ -117,7 +124,8 @@ ).get_distance_from(target, 1) print( - f'sample method {sample_inst_time = } {inst_sample_dist_from_target = } {num_params_coef = }', + f'QFactor-Sample-JAX {sample_inst_time = } {inst_sample_dist_from_target = }' + f' {num_params_coef = }', ) tic = time.perf_counter() @@ -125,6 +133,8 @@ target, multistarts=num_mutlistarts, method=qfactor_gpu_instantiator, ) full_inst_time = time.perf_counter() - tic -inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from(target, 1) +inst_dist_from_target = orig_10q_block_cir_vu.get_unitary().get_distance_from( + target, 1, +) -print(f'full method {full_inst_time = } {inst_dist_from_target = }') +print(f'QFactor-JAX {full_inst_time = } {inst_dist_from_target = }') diff --git a/examples/heisenberg64_10q_block_036.qasm b/examples/heisenberg64_10q_block_036.qasm deleted file mode 100644 index 43b2f4e..0000000 --- a/examples/heisenberg64_10q_block_036.qasm +++ /dev/null @@ -1,108 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[3]; -cx q[2], q[3]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[9]; -u3(0.0, 0.0, 0.02) q[3]; -cx q[2], q[3]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[2]; -u3(0.0, 1.406583, -1.406583) q[3]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, 0.0, 0.02) q[2]; -u3(0.0, 0.0, 0.02) q[4]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[3]; -u3(0.0, 1.406583, -1.406583) q[4]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(0.0, 0.0, 0.04) q[1]; -u3(0.0, 0.0, 0.02) q[3]; -u3(0.0, 0.0, 0.02) q[5]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[4]; -u3(0.0, 1.406583, -1.406583) q[5]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(0.0, 0.0, 0.04) q[2]; -u3(0.0, 0.0, 0.02) q[4]; -u3(0.0, 0.0, 0.02) q[6]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[1]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[5]; -u3(0.0, 1.406583, -1.406583) q[6]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, 0.0, 0.04) q[3]; -u3(0.0, 0.0, 0.02) q[5]; -u3(0.0, 0.0, 0.02) q[7]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[6]; -u3(0.0, 1.406583, -1.406583) q[7]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, 0.0, 0.04) q[4]; -u3(0.0, 0.0, 0.02) q[6]; -u3(0.0, 0.0, 0.02) q[8]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[6]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[7]; -u3(0.0, 1.406583, -1.406583) q[8]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.04) q[5]; -u3(0.0, 0.0, 0.02) q[7]; -u3(0.0, 0.0, 0.02) q[9]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[7]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[8]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, 1.406583, -1.406583) q[9]; -u3(0.0, 0.0, 0.04) q[6]; -u3(0.0, 0.0, 0.02) q[8]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -cx q[6], q[7]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[8]; -u3(0.0, 0.0, 0.04) q[7]; -cx q[6], q[7]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; diff --git a/examples/heisenberg64_10q_block_100.qasm b/examples/heisenberg64_10q_block_100.qasm deleted file mode 100644 index e8aa92f..0000000 --- a/examples/heisenberg64_10q_block_100.qasm +++ /dev/null @@ -1,91 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[2]; -cx q[1], q[2]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[3]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[5]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[6]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[7]; -u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[8]; -u3(1.5707963267948966, 0.0, 3.141592653589793) q[9]; -u3(0.0, 0.0, 0.02) q[2]; -cx q[1], q[2]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[1]; -u3(0.0, 1.406583, -1.406583) q[2]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.0, 0.0, 0.02) q[1]; -u3(0.0, 0.0, 0.02) q[3]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[0]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[1]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[2]; -u3(0.0, 1.406583, -1.406583) q[3]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, 0.0, 0.02) q[2]; -u3(0.0, 0.0, 0.02) q[4]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[2]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[3]; -u3(0.0, 1.406583, -1.406583) q[4]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(0.0, 0.0, 0.02) q[3]; -u3(0.0, 0.0, 0.02) q[5]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[3]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[4]; -u3(0.0, 1.406583, -1.406583) q[5]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(0.0, 0.0, 0.02) q[4]; -u3(0.0, 0.0, 0.02) q[6]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[4]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[5]; -u3(0.0, 1.406583, -1.406583) q[6]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, 0.0, 0.02) q[5]; -u3(0.0, 0.0, 0.02) q[7]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[5]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[6]; -u3(0.0, 1.406583, -1.406583) q[7]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, 0.0, 0.02) q[6]; -u3(0.0, 0.0, 0.02) q[8]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[6]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[7]; -u3(0.0, 1.406583, -1.406583) q[8]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.02) q[7]; -u3(0.0, 0.0, 0.02) q[9]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[7]; -u3(1.5707963267948966, 0.0, 1.5707963267948966) q[8]; -cx q[7], q[8]; -u3(0.0, 1.406583, -1.406583) q[9]; -u3(0.0, 0.0, 0.02) q[8]; -cx q[7], q[8]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -u3(0.0, -3.141592653589793, -3.141592653589793) q[8]; diff --git a/examples/heisenberg64_10q_block_104.qasm b/examples/heisenberg64_10q_block_104.qasm new file mode 100644 index 0000000..d878485 --- /dev/null +++ b/examples/heisenberg64_10q_block_104.qasm @@ -0,0 +1,57 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[1]; +cx q[0], q[1]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[2]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[3]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[4]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[5]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[6]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[7]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[8]; +u3(1.5707963267948966, -3.141592653589793, -3.141592653589793) q[9]; +u3(0.0, 0.0, 0.02) q[1]; +cx q[0], q[1]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[0]; +u3(0.0, 1.406583, -1.406583) q[1]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.02) q[2]; +cx q[1], q[2]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[1]; +u3(0.0, 1.406583, -1.406583) q[2]; +cx q[2], q[3]; +u3(0.0, 0.0, 0.02) q[3]; +cx q[2], q[3]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[2]; +u3(0.0, 1.406583, -1.406583) q[3]; +cx q[3], q[4]; +u3(0.0, 0.0, 0.02) q[4]; +cx q[3], q[4]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[3]; +u3(0.0, 1.406583, -1.406583) q[4]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.02) q[5]; +cx q[4], q[5]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[4]; +u3(0.0, 1.406583, -1.406583) q[5]; +cx q[5], q[6]; +u3(0.0, 0.0, 0.02) q[6]; +cx q[5], q[6]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[5]; +u3(0.0, 1.406583, -1.406583) q[6]; +cx q[6], q[7]; +u3(0.0, 0.0, 0.02) q[7]; +cx q[6], q[7]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[6]; +u3(0.0, 1.406583, -1.406583) q[7]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.02) q[8]; +cx q[7], q[8]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[7]; +u3(0.0, 1.406583, -1.406583) q[8]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.02) q[9]; +cx q[8], q[9]; +u3(1.5707963267948966, 0.0, 1.5707963267948966) q[8]; +u3(0.0, 1.406583, -1.406583) q[9]; diff --git a/examples/shor26_10q_block_051.qasm b/examples/shor26_10q_block_051.qasm deleted file mode 100644 index e1c763a..0000000 --- a/examples/shor26_10q_block_051.qasm +++ /dev/null @@ -1,341 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -cx q[1], q[8]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.35588354) q[0]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.92730176717959) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.71176709) q[0]; -u3(0.0, 0.0, 5.92730175358979) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.57141821717959) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.4235342) q[0]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 4.85965110717959) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.276272) q[0]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.00691330717959) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.9817477042468103) q[0]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.30143760293278) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -cx q[1], q[2]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[1], q[2]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[2]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[0], q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[0], q[2]; -cx q[1], q[8]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[2]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.35588354) q[8]; -u3(0.0, 0.0, 5.92730176717959) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.35588354) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.57141821717959) q[0]; -u3(0.0, 0.0, 0.3558835) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.71176709) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 4.85965110717959) q[0]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.4235342) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.00691330717959) q[0]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.276272) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.30143760293278) q[0]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.9817477042468103) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -cx q[1], q[2]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[1], q[2]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[2]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[0], q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[0], q[2]; -cx q[1], q[8]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[2]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -u3(0.0, 0.0, 0.35588354) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[0], q[8]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.92730176717959) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.35588354) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.71176709) q[0]; -u3(0.0, 0.0, 5.92730176717959) q[8]; -cx q[0], q[7]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.57141821717959) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.71176709) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.4235342) q[0]; -u3(0.0, 0.0, 5.57141821717959) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 4.85965110717959) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 1.4235342) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 1.276272) q[0]; -u3(0.0, 0.0, 4.85965110717959) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.00691330717959) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 1.276272) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.9817477042468103) q[0]; -u3(0.0, 0.0, 5.00691330717959) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.30143760293278) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.9817477042468103) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -u3(0.0, 0.0, 5.30143760293278) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -cx q[1], q[2]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[1], q[2]; -u3(0.0, 0.0, 0.39269908169872414) q[3]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.890486225480862) q[3]; -cx q[0], q[2]; -u3(0.0, 0.0, 5.497787143782138) q[2]; -cx q[0], q[2]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[0], q[2]; -u3(0.0, 0.0, 0.7853981633974483) q[2]; -cx q[0], q[2]; -u3(0.0, 0.0, 5.497787143782138) q[2]; diff --git a/examples/shor26_10q_block_134.qasm b/examples/shor26_10q_block_134.qasm deleted file mode 100644 index c0b7e6c..0000000 --- a/examples/shor26_10q_block_134.qasm +++ /dev/null @@ -1,537 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[10]; -cx q[1], q[8]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.25864161457342) q[0]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.02454369260617026) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -u3(0.0, 0.0, 0.0245436999999999) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[0], q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[0], q[3]; -cx q[1], q[8]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[3]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -u3(0.0, 0.0, 0.02454369260617026) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.25864161457342) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -u3(0.0, 0.0, 6.25864165358979) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[0], q[3]; -cx q[1], q[8]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[3]; -cx q[1], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -u3(0.0, 0.0, 6.25864161457342) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.02454369260617026) q[0]; -cx q[1], q[7]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[1], q[7]; -u3(0.0, 0.0, 6.25864161457342) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -u3(0.0, 0.0, 0.02454369260617026) q[8]; -cx q[0], q[7]; -cx q[2], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[7]; -cx q[2], q[8]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -cx q[1], q[6]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[1], q[6]; -u3(0.0, 0.0, 6.23409792196725) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[6]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -cx q[1], q[5]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[1], q[5]; -u3(0.0, 0.0, 6.18501053675491) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[5]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -cx q[1], q[4]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[1], q[4]; -u3(0.0, 0.0, 6.08683576633022) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[4]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[1], q[3]; -u3(0.0, 0.0, 5.890486225480862) q[4]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[4]; -cx q[0], q[3]; -u3(0.0, 0.0, 0.7853981633974483) q[3]; -cx q[0], q[3]; -cx q[1], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[0], q[3]; -u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[1]; -u3(0.0, 0.0, 5.497787143782138) q[3]; -cx q[0], q[3]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -u3(10.995574287564276, 0.0, 2.356194490192345) q[3]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[8]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -cx q[2], q[7]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[2], q[7]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -u3(0.0, 0.0, 0.0490873732051035) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -cx q[2], q[6]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[2], q[6]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -cx q[2], q[5]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[2], q[5]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -cx q[2], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[2], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[0], q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[0], q[4]; -cx q[2], q[8]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[4]; -cx q[2], q[8]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[8]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -cx q[2], q[7]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[2], q[7]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -u3(0.0, 0.0, 6.23409795358979) q[8]; -cx q[0], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -cx q[2], q[6]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[2], q[6]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -cx q[2], q[5]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[2], q[5]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -cx q[2], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[2], q[4]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[0], q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[0], q[4]; -cx q[2], q[8]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[4]; -cx q[2], q[8]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -u3(0.0, 0.0, 6.23409792196725) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[8]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[0]; -cx q[2], q[7]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[2], q[7]; -u3(0.0, 0.0, 6.23409792196725) q[8]; -cx q[0], q[8]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.18501053675491) q[0]; -u3(0.0, 0.0, 0.04908738521234052) q[8]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[7]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[0]; -cx q[2], q[6]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[2], q[6]; -u3(0.0, 0.0, 6.18501053675491) q[7]; -cx q[0], q[7]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 6.08683576633022) q[0]; -u3(0.0, 0.0, 0.09817477042468103) q[7]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[6]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[0]; -cx q[2], q[5]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[2], q[5]; -u3(0.0, 0.0, 6.08683576633022) q[6]; -cx q[0], q[6]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.890486225480862) q[0]; -u3(0.0, 0.0, 0.19634954084936207) q[6]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[5]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[0]; -cx q[2], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[2], q[4]; -u3(0.0, 0.0, 5.890486225480862) q[5]; -cx q[0], q[5]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 5.497787143782138) q[0]; -u3(0.0, 0.0, 0.39269908169872414) q[5]; -cx q[0], q[4]; -u3(0.0, 0.0, 0.7853981633974483) q[4]; -cx q[0], q[4]; -cx q[2], q[0]; -u3(0.0, 0.0, 0.7853981633974483) q[0]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[0], q[4]; -u3(1.5707963267948966, 4.71238898038469, 1.5707963267948966) q[2]; -u3(0.0, 0.0, 5.497787143782138) q[4]; -cx q[0], q[4]; -u3(10.995574287564276, 0.0, 2.356194490192345) q[4]; diff --git a/examples/vqe12_10q_block145.qasm b/examples/vqe12_10q_block145.qasm new file mode 100644 index 0000000..e6db212 --- /dev/null +++ b/examples/vqe12_10q_block145.qasm @@ -0,0 +1,60 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +cx q[9], q[8]; +u3(1.5707963267948966, 1.5707963267948966, -1.5707963267948966) q[8]; +cx q[8], q[7]; +cx q[7], q[6]; +cx q[6], q[5]; +cx q[5], q[4]; +cx q[4], q[3]; +cx q[3], q[2]; +cx q[2], q[1]; +cx q[1], q[0]; +u3(0.0, 0.0, -0.379188312199599) q[0]; +cx q[1], q[0]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[0]; +cx q[2], q[1]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[1]; +cx q[3], q[2]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[2]; +cx q[4], q[3]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[3]; +cx q[5], q[4]; +cx q[6], q[5]; +u3(1.5707963267948966, 1.5707963267948966, -1.5707963267948966) q[5]; +cx q[7], q[6]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[6]; +cx q[8], q[7]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[7]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; +cx q[9], q[8]; +cx q[8], q[7]; +cx q[7], q[6]; +cx q[6], q[5]; +cx q[5], q[3]; +cx q[3], q[2]; +cx q[2], q[1]; +cx q[1], q[0]; +u3(0.0, 0.0, 0.379188312199599) q[0]; +cx q[1], q[0]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[0]; +cx q[2], q[1]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[1]; +cx q[3], q[2]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[2]; +cx q[5], q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +cx q[6], q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +cx q[7], q[6]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[6]; +cx q[8], q[7]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[7]; +cx q[9], q[8]; +u3(0.0, 1.4065829705916304, -1.4065829705916302) q[8]; +cx q[9], q[8]; +cx q[8], q[7]; +cx q[7], q[6]; +cx q[6], q[5]; +cx q[5], q[4]; From e3c1d998600da170427cdf84544e44a75b0d7b90 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:34:58 -0700 Subject: [PATCH 50/59] pre-commit fix --- examples/compare_state_sample_to_orig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_state_sample_to_orig.py index b450d7f..ce9da82 100644 --- a/examples/compare_state_sample_to_orig.py +++ b/examples/compare_state_sample_to_orig.py @@ -124,7 +124,8 @@ ).get_distance_from(target, 1) print( - f'QFactor-Sample-JAX {sample_inst_time = } {inst_sample_dist_from_target = }' + f'QFactor-Sample-JAX {sample_inst_time = } ' + f'{inst_sample_dist_from_target = }' f' {num_params_coef = }', ) From 04d1f557468e6e5f77654111ce516b648a958875 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:36:25 -0700 Subject: [PATCH 51/59] renaming --- ...ate_sample_to_orig.py => compare_qfactor_sample_to_qfactor.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{compare_state_sample_to_orig.py => compare_qfactor_sample_to_qfactor.py} (100%) diff --git a/examples/compare_state_sample_to_orig.py b/examples/compare_qfactor_sample_to_qfactor.py similarity index 100% rename from examples/compare_state_sample_to_orig.py rename to examples/compare_qfactor_sample_to_qfactor.py From f5c4a00cfb12204ab575b29247e56b2d85431b8b Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:46:04 -0700 Subject: [PATCH 52/59] Removing the sh script --- job.sh | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 job.sh diff --git a/job.sh b/job.sh deleted file mode 100644 index e6da050..0000000 --- a/job.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -#SBATCH --job-name=checking_run_time_var -#SBATCH -A m4141_g -#SBATCH -C gpu -#SBATCH -q regular -#SBATCH -t 8:50:00 -#SBATCH -n 1 -#SBATCH --mem=0 -#SBATCH --ntasks-per-node=1 -#SBATCH --gpus-per-task=1 -#SBATCH --output=./logs/comparing_full_and_sample-shor_10q-%j.txt - - - - -date -uname -a -module load python -module load nvidia -conda activate my_env -nvidia-cuda-mps-control -d - - -XLA_PYTHON_CLIENT_PREALLOCATE=False python ./examples/compare_state_sample_to_orig.py examples/shor26_10q_block_134.qasm 1e-9 0.05 \ No newline at end of file From 759d13db8f93f7654ebaee5ffbaec8e3db25d7b0 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:56:27 -0700 Subject: [PATCH 53/59] Setting the JAX env to only use CPUs --- setup.cfg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index ac307d3..bc4f38f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = bqskit-qfactor-jax -version = 0.0.1 +version = 1.0.0 description = QFactor GPU implementation in BQSKit using JAX long_description = file: README.md long_description_content_type = text/markdown @@ -59,6 +59,9 @@ testpaths = tests/ python_files = test*.py norecursedirs = .env +[pytestenv] +JAX_PLATFORMS = cpu + [mypy] check_untyped_defs = true disallow_any_generics = true From 069b0f5c1c8d2bddf80da520b79f2a390add4dbb Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 00:56:39 -0700 Subject: [PATCH 54/59] Updating year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1325218..ebdb3b6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2023, +Quantum Fast Circuit Optimizer (QFactor) JAX implementation Copyright (c) 2024, U.S. Federal Government and the Government of Israel. All rights reserved. Redistribution and use in source and binary forms, with or without From 1b13445a7e72dc4e2be19fdaa0f695ff0b0e9b49 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 11:05:31 -0700 Subject: [PATCH 55/59] In CI installing jax only for CPU --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index be86af8..287114c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: - name: Upgrade test dependencies run: python -m pip install psutil pytest 'hypothesis[zoneinfo]' qiskit - name: Install JAX - run: pip install -U "jax[cuda12_pip]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html + run: pip install jax - name: Install QFactor JAX run: pip install . - name: Run tests From 8bc3ef9e9bfc8255ad9496b090def42dc03da74c Mon Sep 17 00:00:00 2001 From: alonkukl Date: Tue, 2 Jul 2024 11:36:35 -0700 Subject: [PATCH 56/59] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69dea26..73268c0 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ pip install bqskit-qfactor-jax # Running bqskit-qfactor-jax Please set the environment variable XLA_PYTHON_CLIENT_PREALLOCATE=False when using this package. Also, if you encounter OOM issues consider setting XLA_PYTHON_CLIENT_ALLOCATOR=platform. -Please take a look at the [examples](https://github.com/BQSKit/bqskit-qfactor-jax/tree/main/examples) to see some basic usage. +Please look at the [examples](https://github.com/BQSKit/bqskit-qfactor-jax/tree/main/examples) for basic usage, especially at performance comparison between QFactor and QFactor-Sample. When using several workers on the same GPU, we recommend using [Nvidia's MPS](https://docs.nvidia.com/deploy/mps/index.html). You may initiate it using the command line ```sh From c787dc2049612f083fae69d6316b38c10b090ca2 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 11:38:16 -0700 Subject: [PATCH 57/59] No need for this here --- setup.cfg | 3 --- 1 file changed, 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index bc4f38f..5477a32 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,9 +59,6 @@ testpaths = tests/ python_files = test*.py norecursedirs = .env -[pytestenv] -JAX_PLATFORMS = cpu - [mypy] check_untyped_defs = true disallow_any_generics = true From fce457528cea0c75394b2a47a584ccee4f5844d7 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 12:40:13 -0700 Subject: [PATCH 58/59] Adding a new line in the references --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 73268c0..089cdde 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ echo quit | nvidia-cuda-mps-control ``` # References -If you are using QFactor-JAX please cite: +If you are using QFactor-JAX please cite:\ Kukliansky, Alon, et al. "QFactor: A Domain-Specific Optimizer for Quantum Circuit Instantiation." 2023 IEEE International Conference on Quantum Computing and Engineering (QCE). Vol. 1. IEEE, 2023. [Link](https://ieeexplore.ieee.org/abstract/document/10313638). -If you are using QFactor-Sample please cite: +If you are using QFactor-Sample please cite:\ Kukliansky, Alon, et al. "Leveraging Quantum Machine Learning Generalization to Significantly Speed-up Quantum Compilation" arXiv preprint [arXiv:2405.12866](https://arxiv.org/abs/2405.12866) (2024). ## License From d460bbfbfd29bad3bd947d8c58f207269d967f51 Mon Sep 17 00:00:00 2001 From: Alon Kukliansky Date: Tue, 2 Jul 2024 12:40:31 -0700 Subject: [PATCH 59/59] Adding python 3.12 to the list --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 287114c..e9f6060 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] os: [ubuntu-latest] runs-on: ${{ matrix.os }}