From 9ea4108ff11898316c2d8d43c444d148c8ebac7b Mon Sep 17 00:00:00 2001 From: alexva Date: Tue, 29 Oct 2019 14:58:12 -0700 Subject: [PATCH 01/12] QuantumExecutor interface. --- src/Simulation/Common/IQuantumExecutor.cs | 568 ++++++++++++++++++ src/Simulation/Common/Utils.cs | 66 ++ .../Simulators/QuantumExecutor/Allocate.cs | 29 + .../Simulators/QuantumExecutor/Assert.cs | 41 ++ .../Simulators/QuantumExecutor/AssertProb.cs | 43 ++ .../Simulators/QuantumExecutor/Borrow.cs | 29 + .../QuantumExecutor/ClassicalControl.cs | 116 ++++ .../QuantumExecutor/ClassicalControl.qs | 124 ++++ .../Simulators/QuantumExecutor/Dump.cs | 67 +++ .../QuantumExecutor/EmptyQuantumExecutor.cs | 231 +++++++ .../Simulators/QuantumExecutor/Exp.cs | 62 ++ .../Simulators/QuantumExecutor/ExpFrac.cs | 65 ++ .../Simulators/QuantumExecutor/H.cs | 36 ++ .../Simulators/QuantumExecutor/M.cs | 26 + .../Simulators/QuantumExecutor/Measure.cs | 35 ++ .../QuantumExecutorSimulator.cs | 46 ++ .../Simulators/QuantumExecutor/R.cs | 54 ++ .../Simulators/QuantumExecutor/R1.cs | 51 ++ .../Simulators/QuantumExecutor/R1Frac.cs | 53 ++ .../Simulators/QuantumExecutor/RFrac.cs | 56 ++ .../Simulators/QuantumExecutor/Release.cs | 27 + .../Simulators/QuantumExecutor/Reset.cs | 27 + .../Simulators/QuantumExecutor/Return.cs | 27 + .../Simulators/QuantumExecutor/S.cs | 49 ++ .../Simulators/QuantumExecutor/SWAP.cs | 35 ++ .../Simulators/QuantumExecutor/T.cs | 52 ++ .../Simulators/QuantumExecutor/X.cs | 35 ++ .../Simulators/QuantumExecutor/Y.cs | 35 ++ .../Simulators/QuantumExecutor/Z.cs | 35 ++ .../Simulators/QuantumExecutor/random.cs | 52 ++ 30 files changed, 2172 insertions(+) create mode 100644 src/Simulation/Common/IQuantumExecutor.cs create mode 100644 src/Simulation/Common/Utils.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Allocate.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Assert.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/AssertProb.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Borrow.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Dump.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Exp.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/H.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/M.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Measure.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/R.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/R1.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/R1Frac.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/RFrac.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Release.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Reset.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Return.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/S.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/SWAP.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/T.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/X.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Y.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/Z.cs create mode 100644 src/Simulation/Simulators/QuantumExecutor/random.cs diff --git a/src/Simulation/Common/IQuantumExecutor.cs b/src/Simulation/Common/IQuantumExecutor.cs new file mode 100644 index 00000000000..935a217ed75 --- /dev/null +++ b/src/Simulation/Common/IQuantumExecutor.cs @@ -0,0 +1,568 @@ +ο»Ώusing System; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + /// + /// An interface for implementing QDK target machines which work + /// on a quantum circuit level. + /// It is intended to be used with . + /// + /// + /// Simulators implemented using interface do not manage qubits on their own. + /// Instead they are notified when qubits are allocated, released, borrowed and returned. + /// + public interface IQuantumExecutor + { + /// + /// Called when Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to . + /// + /// + /// When adjoint of R is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Pauli operator to be exponentiated to form the rotation. + /// Angle about which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void R(Pauli axis, double theta, Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to controlled on . + /// + /// + /// When adjoint of Controlled R is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Pauli operator to be exponentiated to form the rotation. + /// Angle about which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.RFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// + /// + /// When adjoint of RFrac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Pauli operator to be exponentiated to form the rotation. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void RFrac(Pauli axis, long numerator, long power, Qubit qubit); + + /// + /// Called when a controlled Microsoft.Quantum.Intrinsic.RFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// + /// + /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Pauli operator to be exponentiated to form the rotation. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Exp is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to . + /// + /// + /// When adjoint of Exp is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. + /// Register to apply the exponent to. + void Exp(IQArray paulis, double theta, IQArray qubits); + + /// + /// Called when a controlled Microsoft.Quantum.Intrinsic.Exp is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to controlled on . + /// + /// + /// When adjoint of Controlled Exp is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. + /// Register to apply the exponent to. + void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits); + + /// + /// Called when Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// + /// + /// When adjoint of ExpFrac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. + /// Register to apply the exponent to. + void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// + /// + /// When adjoint of Controlled ExpFrac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. + /// Register to apply the exponent to. + void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits); + + /// + /// Called when Microsoft.Quantum.Intrinsic.H is called in Q#. + /// In Q# the operation applies Hadamard gate to . The gate is given by matrix H=((1,1),(1,-1))/√2. + /// + /// + /// When adjoint of H is called in Q#, is called because Hadamard is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void H(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.H is called in Q#. + /// In Q# the operation applies Hadamard gate to controlled on . The gate is given by matrix H=((1,1),(1,-1))/√2. + /// + /// + /// When adjoint of Controlled H is called in Q#, is called because Hadamard is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledH(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.S is called in Q#. + /// In Q# the operation applies S gate to . The gate is given by matrix S=((1,0),(0,𝑖)). + /// + /// + /// When adjoint of S is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void S(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.S is called in Q#. + /// In Q# the operation applies S gate to controlled on . The gate is given by matrix S=((1,0),(0,𝑖)). + /// + /// + /// When adjoint of Controlled S is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledS(IQArray controls, Qubit qubit); + + /// + /// Called when adjoint Microsoft.Quantum.Intrinsic.S is called in Q#. + /// In Q# the operation applies S† gate to . The gate is given by matrix S†=((1,0),(0,-𝑖)). + /// + /// + /// When adjoint of Adjoint S is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void SAdj(Qubit qubit); + + /// + /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.S is called in Q#. + /// In Q# the operation applies S† gate to controlled on . The gate is given by matrix S†=((1,0),(0,𝑖)). + /// + /// + /// When adjoint of Controlled S† is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledSAdj(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.T is called in Q#. + /// In Q# the operation applies T gate to . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). + /// + /// + /// When adjoint of T is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void T(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.T is called in Q#. + /// In Q# the operation applies T gate to controlled on . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). + /// + /// + /// When adjoint of Controlled T is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledT(IQArray controls, Qubit qubit); + + /// + /// Called when adjoint Microsoft.Quantum.Intrinsic.T is called in Q#. + /// In Q# the operation applies T† gate to . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). + /// + /// + /// When adjoint of Adjoint T is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void TAdj(Qubit qubit); + + /// + /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.T is called in Q#. + /// In Q# the operation applies T† gate to controlled on . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). + /// + /// + /// When adjoint of Controlled T† is called in Q#, is called. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledTAdj(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.M is called in Q#. + /// In Q# the operation measures in Z basis, in other words in the computational basis. + /// + /// + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// Class implementing interface can return any class derived from . + /// + /// Qubit to which the gate should be applied. + /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. + Result M(Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Measure is called in Q#. + /// In Q# the operation measures multi-qubit Pauli observable given by on . + /// + /// + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// Class implementing interface can return any class derived from . + /// + /// Qubits to which the gate should be applied. + /// Array of single-qubit Pauli values describing multi-qubit Pauli observable. + /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. + Result Measure(IQArray bases, IQArray qubits); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Reset is called in Q#. + /// In Q# the operation, measures and ensures it is in the |0⟩ state such that it can be safely released. + /// + /// + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void Reset(Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// + /// + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. + /// A register on which to make the assertion. + /// The expected result of Measure(bases, qubits) + /// A message to be reported if the assertion fails. + void Assert(IQArray bases, IQArray qubits, Result result, string msg); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// + /// + /// The names and the order of the parameters is similar to the corresponding Q# operation./ + /// + /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. + /// A register on which to make the assertion. + /// The probability with which result Zero is expected. + /// A message to be reported if the assertion fails. + /// The precision with which the probability of Zero outcome is specified. + void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol); + + /// + /// Called when Microsoft.Quantum.Intrinsic.X is called in Q#. + /// In Q# the operation applies X gate to . The gate is given by matrix X=((0,1),(1,0)). + /// + /// + /// When adjoint of X is called in Q#, is called because X is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void X(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.X is called in Q#. + /// In Q# the operation applies X gate to controlled on . The gate is given by matrix X=((0,1),(1,0)). + /// + /// + /// When adjoint of Controlled X is called in Q#, is called because X is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledX(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Y is called in Q#. + /// In Q# the operation applies Y gate to . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// + /// + /// When adjoint of Y is called in Q#, is called because Y is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void Y(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.Y is called in Q#. + /// In Q# the operation applies X gate to controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// + /// + /// When adjoint of Controlled Y is called in Q#, is called because Y is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledY(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Z is called in Q#. + /// In Q# the operation applies Z gate to . The gate is given by matrix Z=((1,0),(0,-1)). + /// + /// + /// When adjoint of Z is called in Q#, is called because Z is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Qubit to which the gate should be applied. + void Z(Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.Z is called in Q#. + /// In Q# the operation applies Z gate to controlled on . The gate is given by matrix Z=((1,0),(0,-1)). + /// + /// + /// When adjoint of Controlled Z is called in Q#, is called because Z is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Qubit to which the gate should be applied. + void ControlledZ(IQArray controls, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.R1 is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to . + /// + /// + /// When adjoint of R1 is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Angle about which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void R1(double theta, Qubit qubit); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to controlled on . + /// + /// + /// When adjoint of Controlled R1 is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Angle about which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledR1(IQArray controls, double theta, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to . + /// + /// + /// When adjoint of R1Frac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void R1Frac(long numerator, long power, Qubit qubit); + + /// + /// Called when a controlled Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to controlled on . + /// + /// + /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit); + + /// + /// Called when Microsoft.Quantum.Intrinsic.SWAP is called in Q#. + /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states. + /// + /// + /// When adjoint of SWAP is called in Q#, is called because SWAP is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// First qubit to be swapped. + /// Second qubit to be swapped. + void SWAP(Qubit qubit1, Qubit qubit2); + + /// + /// Called when controlled Microsoft.Quantum.Intrinsic.SWAP is called in Q#. + /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states controlled on . + /// + /// + /// When adjoint of Controlled SWAP is called in Q#, is called because SWAP is self-adjoint. + /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// + /// The array of qubits on which the operation is controlled. + /// First qubit to be swapped. + /// Second qubit to be swapped. + void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2); + + /// + /// Called before a call to any Q# operation. + /// + /// Information about operation being called. + /// Information about the arguments passed to the operation. + /// + /// To get the fully qualified Q# name of operation being called use . + /// For the variant of operation, that is to find if Adjoint, Controlled or Controlled Adjoint being called use . + /// To get a sequence of all qubits passed to the operation use . + /// + void OnOperationStart(ICallable operation, IApplyData arguments); + + /// + /// Called when returning from a call to any Q# operation. + /// + /// Information about operation being called. + /// Information about the arguments passed to the operation. + /// + /// To get the fully qualified Q# name of operation being called use . + /// For the variant of operation, that is to find if Adjoint, Controlled or Controlled Adjoint being called use . + /// To get a sequence of all qubits passed to the operation use . + /// + void OnOperationEnd(ICallable operation, IApplyData arguments); + + /// + /// Called in the end of the call to any Q# operation. + /// + /// Information about exception that was raised. + /// + /// + void OnFail(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo); + + /// + /// Intended for a limited support of branching upon measurement results on a simulator level. + /// + /// The result of the measurement upon which branching is to be performed. + /// Corresponds to quantum program that must be executed if result is + /// Corresponds to quantum program that must be executed if result is + /// + /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . + /// The program is executed with the same instance of interface. + /// + void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); + + /// + /// Called when qubits are allocated by Q# using block. + /// + /// Qubits that are allocated. + /// + /// Every qubit in simulation framework has a unique identifier . + /// All newly allocated qubits are in |0⟩ state. + /// + void OnAllocateQubits(IQArray qubits); + + /// + /// Called when qubits are released in Q# in the end of using block. + /// + /// Qubits that are released. + /// + /// Every qubit in simulation framework has a unique identifier . + /// All qubits are expected to be released in |0⟩ state. + /// + void OnReleaseQubits(IQArray qubits); + + /// + /// Called when qubits are borrowed by Q# borrowing block. + /// + /// Qubits that are borrowed. + /// + /// Every qubit in simulation framework has a unique identifier . + /// Borrowed qubits can be in any state. + /// + void OnBorrowQubits(IQArray qubits); + + /// + /// Called when qubits are returned in the end of Q# borrowing block. + /// + /// Qubits that has been allocated. + /// + /// Every qubit in simulation framework has a unique identifier . + /// Borrowed qubits are expected to be returned in the same state as the state they have been borrowed in. + /// + void OnReturnQubits(IQArray qubits); + + /// + /// Called when + /// Microsoft.Quantum.Diagnostics.DumpMachine + /// is called in Q#. + /// + /// + /// The names and the order of the parameters are similar to corresponding Q# operation. + /// + /// + /// Provides information on where to generate the DumpMachine state. + void OnDumpMachine(T location); + + /// + /// Called when + /// Microsoft.Quantum.Diagnostics.DumpRegister + /// is called in Q#. + /// + /// + /// The names and the order of the parameters are similar to corresponding Q# operation. + /// + /// + /// Provides information on where to generate the DumpRegister state. + /// The list of qubits to report. + void OnDumpRegister(T location, IQArray qubits); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Message is called in Q#. + /// + /// + /// The names and the order of the parameters are the same as corresponding Q# operations. + /// + /// The message to be reported. + void OnMessage(string msg); + } +} diff --git a/src/Simulation/Common/Utils.cs b/src/Simulation/Common/Utils.cs new file mode 100644 index 00000000000..6850ad7975d --- /dev/null +++ b/src/Simulation/Common/Utils.cs @@ -0,0 +1,66 @@ +ο»Ώusing Microsoft.Quantum.Intrinsic; +using Microsoft.Quantum.Simulation.Core; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Microsoft.Quantum.Simulation.Common +{ + public class CommonUtils + { + /// + /// Removes PauliI terms from observable and corresponding qubits from qubits. + /// Returns the observable description that is equivalent to the original one, but has no PauliI terms + /// + public static void PruneObservable(IQArray observable, IQArray qubits, out QArray prunnedObservable, out QArray prunnedQubits) + { + Debug.Assert(observable != null); + Debug.Assert(qubits != null); + Debug.Assert(observable.Length == qubits.Length); + prunnedObservable = new QArray(PrunnedSequence(observable, Pauli.PauliI, observable)); + prunnedQubits = new QArray(PrunnedSequence(observable, Pauli.PauliI, qubits)); + } + + /// + /// Returns IEnumerable that contains sub-sequence of [i], such that [i] is not equal to . + /// + public static IEnumerable PrunnedSequence(IQArray sequence, U value, IQArray sequenceToPrune ) + { + for (uint i = 0; i < sequence.Length; ++i) + { + if (!sequence[i].Equals(value)) + { + yield return sequenceToPrune[i]; + } + } + } + + /// + /// Converts numbers of the form /2^ into canonical form where is odd or zero. + /// If is zero, must also be zero in the canonical form. + /// + public static (long, long) Reduce(long numerator, long denominatorPower) + { + if (numerator == 0) + { + return (0, 0); + } + + if (numerator % 2 != 0) + { + return (numerator, denominatorPower); + } + + long numNew = numerator; + long denomPowerNew = denominatorPower; + + while (numNew % 2 == 0) + { + numNew /= 2; + denomPowerNew -= 1; + } + + return (numNew, denomPowerNew); + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Allocate.cs b/src/Simulation/Simulators/QuantumExecutor/Allocate.cs new file mode 100644 index 00000000000..5f8c9c336ac --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Allocate.cs @@ -0,0 +1,29 @@ +ο»Ώusing Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimAllocate : Intrinsic.Allocate + { + private readonly QuantumExecutorSimulator sim; + public QuantumExecutorSimAllocate(QuantumExecutorSimulator m) : base(m){ + sim = m; + } + + public override Qubit Apply() + { + IQArray qubits = sim.QubitManager.Allocate(1); + sim.QuantumExecutor.OnAllocateQubits(qubits); + return qubits[0]; + } + + public override IQArray Apply( long count ) + { + IQArray qubits = sim.QubitManager.Allocate(count); + sim.QuantumExecutor.OnAllocateQubits(qubits); + return qubits; + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/Assert.cs b/src/Simulation/Simulators/QuantumExecutor/Assert.cs new file mode 100644 index 00000000000..fef0b748262 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Assert.cs @@ -0,0 +1,41 @@ +ο»Ώusing System; +using System.Collections.Generic; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimAssert : Quantum.Intrinsic.Assert + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimAssert(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(IQArray, IQArray, Result, string), QVoid> Body => (_args) => + { + var (paulis, qubits, result, msg) = _args; + if (paulis.Length != qubits.Length) + { + IgnorableAssert.Assert((paulis.Length != qubits.Length), "Arrays length mismatch"); + throw new InvalidOperationException($"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); + } + + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + Simulator.QuantumExecutor.Assert(newPaulis, newQubits, result, msg); + + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray, Result, string), QVoid> AdjointBody => (_args) => { return QVoid.Instance; }; + + public override Func<(IQArray, (IQArray, IQArray, Result, string)), QVoid> ControlledBody => (_args) => { return QVoid.Instance; }; + + public override Func<(IQArray, (IQArray, IQArray, Result, string)), QVoid> ControlledAdjointBody => (_args) => { return QVoid.Instance; }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs b/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs new file mode 100644 index 00000000000..da8446aa8c8 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs @@ -0,0 +1,43 @@ +ο»Ώusing System; +using System.Collections.Generic; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimAssertProb : Quantum.Intrinsic.AssertProb + { + + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimAssertProb(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(IQArray, IQArray, Result, double, string, double), QVoid> Body => (_args) => + { + var (paulis, qubits, result, expectedPr, msg, tol) = _args; + if (paulis.Length != qubits.Length) + { + IgnorableAssert.Assert((paulis.Length != qubits.Length), "Arrays length mismatch"); + throw new InvalidOperationException($"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); + } + + double probabilityOfZero = result == Result.Zero ? expectedPr : 1.0 - expectedPr; + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + Simulator.QuantumExecutor.AssertProb(newPaulis, newQubits, probabilityOfZero, msg, tol ); + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray, Result, double, string, double), QVoid> AdjointBody => (_args) => { return QVoid.Instance; }; + + public override Func<(IQArray, (IQArray, IQArray, Result, double, string, double)), QVoid> ControlledBody => (_args) => { return QVoid.Instance; }; + + public override Func<(IQArray, (IQArray, IQArray, Result, double, string, double)), QVoid> ControlledAdjointBody => (_args) => { return QVoid.Instance; }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Borrow.cs b/src/Simulation/Simulators/QuantumExecutor/Borrow.cs new file mode 100644 index 00000000000..82d5062a4f1 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Borrow.cs @@ -0,0 +1,29 @@ +ο»Ώusing Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimBorrow : Intrinsic.Borrow + { + private readonly QuantumExecutorSimulator sim; + public QuantumExecutorSimBorrow(QuantumExecutorSimulator m) : base(m){ + sim = m; + } + + public override Qubit Apply() + { + IQArray qubits = sim.QubitManager.Borrow(1); + sim.QuantumExecutor.OnBorrowQubits(qubits); + return qubits[0]; + } + + public override IQArray Apply( long count ) + { + IQArray qubits = sim.QubitManager.Borrow(1); + sim.QuantumExecutor.OnBorrowQubits(qubits); + return qubits; + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs new file mode 100644 index 00000000000..11eb7bf8ac8 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs @@ -0,0 +1,116 @@ +ο»Ώusing System; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class SimApplyIfElse : Extensions.ApplyIfElseIntrinsic + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyIfElse(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(Result, ICallable, ICallable), QVoid> Body => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + } + + public class SimApplyIfElseA : Extensions.ApplyIfElseIntrinsicA + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyIfElseA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(Result, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Adjoint.Apply(QVoid.Instance), + () => onOne.Adjoint.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + } + + public class SimApplyIfElseC : Extensions.ApplyIfElseIntrinsicC + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyIfElseC(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => + (q) => + { + var (ctrls, (measurementResult, onZero, onOne)) = q; + Simulator.QuantumExecutor.ClassicallyControlled( + measurementResult, () => onZero.Controlled.Apply(ctrls), () => onOne.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; + } + + public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyIfElseCA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(Result, IUnitary, IUnitary), QVoid> AdjointBody => (q) => + { + var (measurementResult, onZero, onOne) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Adjoint.Apply(QVoid.Instance), + () => onOne.Adjoint.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => + { + var (ctrls, (measurementResult, onZero, onOne)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Controlled.Apply(ctrls), + () => onOne.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => + (q) => + { + var (ctrls, (measurementResult, onZero, onOne)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Controlled.Adjoint.Apply(ctrls), + () => onOne.Controlled.Adjoint.Apply(ctrls)); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs new file mode 100644 index 00000000000..07bda4eb33c --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs @@ -0,0 +1,124 @@ +ο»Ώnamespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions +{ + open Microsoft.Quantum.Intrinsic; + + operation NoOp() : Unit is Ctl + Adj {} + + operation Delay<'T> ( op : ('T => Unit), arg : 'T, aux : Unit ) : Unit { + op(arg); + } + + operation DelayC<'T> ( op : ('T => Unit is Ctl), arg : 'T, aux : Unit ) : Unit is Ctl { + op(arg); + } + + operation DelayA<'T> ( op : ('T => Unit is Adj), arg : 'T, aux : Unit ) : Unit is Adj { + op(arg); + } + + operation DelayCA<'T> ( op : ('T => Unit is Ctl + Adj), arg : 'T, aux : Unit ) : Unit is Ctl + Adj { + op(arg); + } + + + operation ApplyIfElseIntrinsic( measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit) ) : Unit { + body intrinsic; + } + + operation ApplyIfElseIntrinsicA( measurementResult : Result, onResultZeroOp : (Unit => Unit is Adj) , onResultOneOp : (Unit => Unit is Adj) ) : Unit { + body intrinsic; + adjoint intrinsic; + } + + operation ApplyIfElseIntrinsicC( measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl) , onResultOneOp : (Unit => Unit is Ctl) ) : Unit { + body intrinsic; + controlled intrinsic; + } + + operation ApplyIfElseIntrinsicCA( measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl + Adj) , onResultOneOp : (Unit => Unit is Ctl + Adj) ) : Unit { + body intrinsic; + adjoint intrinsic; + controlled intrinsic; + controlled adjoint intrinsic; + } + + + operation ApplyIfElse<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) , (onResultOneOp : ('U => Unit), oneArg : 'U) ) : Unit { + let zeroOp = Delay(onResultZeroOp,zeroArg,_); + let oneOp = Delay(onResultOneOp,oneArg,_); + ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + } + +// operation ApplyIfElseArray<'T,'U>( measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit), equalArg : 'T) , (onNonEqualOp : ('U => Unit), nonEqualArg : 'U) ) : Unit { +// let equalOp = Delay(onEqualOp,equalArg,_); +// let nonEqualOp = Delay(onNonEqualOp,nonEqualArg,_); // normalize spaces !!! +// //ApplyIfElseIntrinsic( measurementResults, resultsValues, equalOp, nonEqualOp ); // wrong!!! +// } + + operation ApplyIfElseA<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj), oneArg : 'U) ) : Unit is Adj { + let zeroOp = DelayA(onResultZeroOp,zeroArg,_); + let oneOp = DelayA(onResultOneOp,oneArg,_); + ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfElseC<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Ctl), oneArg : 'U) ) : Unit is Ctl { + let zeroOp = DelayC(onResultZeroOp,zeroArg,_); + let oneOp = DelayC(onResultOneOp,oneArg,_); + ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfElseCA<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj + Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj + Ctl), oneArg : 'U) ) : Unit is Ctl + Adj { + let zeroOp = DelayCA(onResultZeroOp,zeroArg,_); + let oneOp = DelayCA(onResultOneOp,oneArg,_); + ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfZero<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) ) : Unit { + let zeroOp = Delay(onResultZeroOp,zeroArg,_); + let oneOp = Delay(NoOp, (),_); + ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfZeroA<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T) ) : Unit is Adj{ + let zeroOp = DelayA(onResultZeroOp,zeroArg,_); + let oneOp = DelayA(NoOp, (),_); + ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfZeroC<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T) ) : Unit is Ctl { + let zeroOp = DelayC(onResultZeroOp,zeroArg,_); + let oneOp = DelayC(NoOp, (),_); + ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfZeroCA<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl + Adj), zeroArg : 'T) ) : Unit is Ctl + Adj { + let zeroOp = DelayCA(onResultZeroOp,zeroArg,_); + let oneOp = DelayCA(NoOp, (),_); + ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfOne<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit), oneArg : 'T) ) : Unit { + let oneOp = Delay(onResultOneOp,oneArg,_); + let zeroOp = Delay(NoOp, (),_); + ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfOneA<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Adj), oneArg : 'T) ) : Unit is Adj { + let oneOp = DelayA(onResultOneOp,oneArg,_); + let zeroOp = DelayA(NoOp, (),_); + ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfOneC<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl), oneArg : 'T) ) : Unit is Ctl { + let oneOp = DelayC(onResultOneOp,oneArg,_); + let zeroOp = DelayC(NoOp, (),_); + ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + } + + operation ApplyIfOneCA<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl + Adj), oneArg : 'T) ) : Unit is Ctl + Adj { + let oneOp = DelayCA(onResultOneOp,oneArg,_); + let zeroOp = DelayCA(NoOp, (),_); + ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + } + +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Dump.cs b/src/Simulation/Simulators/QuantumExecutor/Dump.cs new file mode 100644 index 00000000000..ce7c997051a --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Dump.cs @@ -0,0 +1,67 @@ +ο»Ώusing System; +using System.IO; +using System.Linq; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + /// + /// Dumps the wave function for the given qubits into the given target. + /// If the target is QVoid or an empty string, it dumps it to the console + /// using the `Message` function, otherwise it dumps the content into a file + /// with the given name. + /// DumpMachine dumps the entire wave function, + /// DumpRegister attempts to create the wave function or the resulting subsystem; if it fails + /// because the qubits are entangled with some external qubit, it just generates a message. + /// + protected virtual QVoid DumpMachine(T target) + { + QuantumExecutor.OnDumpMachine(target); + return QVoid.Instance; + } + + protected virtual QVoid DumpRegister(T target, IQArray qubits) + { + QuantumExecutor.OnDumpRegister(target, qubits); + return QVoid.Instance; + } + + public class QuantumExecutorSimDumpMachine : Quantum.Diagnostics.DumpMachine + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimDumpMachine(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (location) => + { + if (location == null) { throw new ArgumentNullException(nameof(location)); } + + return Simulator.DumpMachine(location); + }; + } + + public class QuantumExecutorSimDumpRegister : Quantum.Diagnostics.DumpRegister + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimDumpRegister(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(T, IQArray), QVoid> Body => (__in) => + { + var (location, qubits) = __in; + + if (location == null) { throw new ArgumentNullException(nameof(location)); } + return Simulator.DumpRegister(location, qubits); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs new file mode 100644 index 00000000000..fc8636c69f7 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs @@ -0,0 +1,231 @@ +ο»Ώusing System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + /// + /// An example of IQuantumExecutor that throws for every call. + /// + class EmptyQuantumExecutor : IQuantumExecutor + { + public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) + { + } + + public virtual void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol) + { + } + + public virtual void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne) + { + throw new NotImplementedException(); + } + + public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) + { + throw new NotImplementedException(); + } + + public virtual void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits) + { + throw new NotImplementedException(); + } + + public virtual void ControlledH(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledR1(IQArray controls, double theta, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledS(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledSAdj(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2) + { + throw new NotImplementedException(); + } + + public virtual void ControlledT(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledTAdj(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledX(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledY(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void ControlledZ(IQArray controls, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void Exp(IQArray paulis, double theta, IQArray qubits) + { + throw new NotImplementedException(); + } + + public virtual void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits) + { + throw new NotImplementedException(); + } + + public virtual void H(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual Result M(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual Result Measure(IQArray bases, IQArray qubits) + { + throw new NotImplementedException(); + } + + public virtual void OnAllocateQubits(IQArray qubits) + { + } + + public virtual void OnBorrowQubits(IQArray qubits) + { + } + + public virtual void OnDumpMachine(T location) + { + } + + public virtual void OnDumpRegister(T location, IQArray qubits) + { + } + + public virtual void OnMessage(string msg) + { + } + + public virtual void OnOperationEnd(ICallable operation, IApplyData arguments) + { + } + + public virtual void OnOperationStart(ICallable operation, IApplyData arguments) + { + } + + public virtual void OnFail(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo) + { + } + + public virtual void OnReleaseQubits(IQArray qubits) + { + } + + public virtual void OnReturnQubits(IQArray qubits) + { + } + + public virtual void R(Pauli axis, double theta, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void R1(double theta, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void R1Frac(long numerator, long power, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void Reset(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void RFrac(Pauli axis, long numerator, long power, Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void S(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void SAdj(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void SWAP(Qubit qubit1, Qubit qubit2) + { + throw new NotImplementedException(); + } + + public virtual void T(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void TAdj(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void X(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void Y(Qubit qubit) + { + throw new NotImplementedException(); + } + + public virtual void Z(Qubit qubit) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Exp.cs b/src/Simulation/Simulators/QuantumExecutor/Exp.cs new file mode 100644 index 00000000000..e809f9dce13 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Exp.cs @@ -0,0 +1,62 @@ +ο»Ώusing System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimExp : Quantum.Intrinsic.Exp + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimExp(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(IQArray, double, IQArray), QVoid> Body => (_args) => + { + + var (paulis, theta, qubits) = _args; + + if (paulis.Length != qubits.Length) + { + throw new InvalidOperationException($"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); + } + + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + Simulator.QuantumExecutor.Exp(newPaulis, theta, newQubits); + + return QVoid.Instance; + }; + + public override Func<(IQArray, double, IQArray), QVoid> AdjointBody => (_args) => + { + var (paulis, angle, qubits) = _args; + return this.Body.Invoke((paulis, -angle, qubits)); + }; + + public override Func<(IQArray, (IQArray, double, IQArray)), QVoid> ControlledBody => (_args) => + { + + var (ctrls, (paulis, theta, qubits)) = _args; + + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + Simulator.QuantumExecutor.ControlledExp(ctrls, newPaulis, theta, newQubits); + + return QVoid.Instance; + }; + + public override Func<(IQArray, (IQArray, double, IQArray)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (paulis, angle, qubits)) = _args; + + return this.ControlledBody.Invoke((ctrls, (paulis, -angle, qubits))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs b/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs new file mode 100644 index 00000000000..7407a42ab99 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs @@ -0,0 +1,65 @@ +ο»Ώusing Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; +using System; +using System.Collections.Generic; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimExpFrac : Quantum.Intrinsic.ExpFrac + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimExpFrac(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(IQArray, long, long, IQArray), QVoid> Body => (_args) => + { + + var (paulis, nom, den, qubits) = _args; + + if (paulis.Length != qubits.Length) + { + throw new InvalidOperationException( + $"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); + } + + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + + Simulator.QuantumExecutor.ExpFrac(newPaulis, nom, den, newQubits); + return QVoid.Instance; + }; + + public override Func<(IQArray, long, long, IQArray), QVoid> AdjointBody => (_args) => + { + var (paulis, nom, den, qubits) = _args; + return this.Body.Invoke((paulis, -nom, den, qubits)); + }; + + public override Func<(IQArray, (IQArray, long, long, IQArray)), QVoid> + ControlledBody => (_args) => + { + + var (ctrls, (paulis, nom, den, qubits)) = _args; + + if (paulis.Length != qubits.Length) + { + throw new InvalidOperationException( + $"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); + } + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + Simulator.QuantumExecutor.ControlledExpFrac(ctrls, newPaulis, nom, den, newQubits); + + return QVoid.Instance; + }; + + public override Func<(IQArray, (IQArray, long, long, IQArray)), QVoid> + ControlledAdjointBody => (_args) => + { + var (ctrls, (paulis, nom, den, qubits)) = _args; + + return this.ControlledBody.Invoke((ctrls, (paulis, -nom, den, qubits))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/H.cs b/src/Simulation/Simulators/QuantumExecutor/H.cs new file mode 100644 index 00000000000..bea3fee8920 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/H.cs @@ -0,0 +1,36 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimH : Quantum.Intrinsic.H + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimH(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.H(q1); + return QVoid.Instance; + }; + + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (args) => + { + + var (ctrls, q1) = args; + Simulator.QuantumExecutor.ControlledH(ctrls,q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/M.cs b/src/Simulation/Simulators/QuantumExecutor/M.cs new file mode 100644 index 00000000000..573ddc3ebc9 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/M.cs @@ -0,0 +1,26 @@ +ο»Ώusing System; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimM : Quantum.Intrinsic.M + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimM(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q) => + { + return Simulator.QuantumExecutor.M(q); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Measure.cs b/src/Simulation/Simulators/QuantumExecutor/Measure.cs new file mode 100644 index 00000000000..6c8c2dd90d7 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Measure.cs @@ -0,0 +1,35 @@ +ο»Ώusing System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimMeasure : Quantum.Intrinsic.Measure + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimMeasure(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(IQArray, IQArray), Result> Body => (_args) => + { + var (paulis, qubits) = _args; + + if (paulis.Length != qubits.Length) + { + throw new InvalidOperationException($"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size"); + } + + CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); + return Simulator.QuantumExecutor.Measure( newPaulis, newQubits); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs new file mode 100644 index 00000000000..bf1ad0cfe91 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs @@ -0,0 +1,46 @@ +ο»Ώusing System; + +using Microsoft.Quantum.Simulation.Common; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + /// + /// Simulator that redirects all the calls to a class implementing interface. + /// + public partial class QuantumExecutorSimulator : SimulatorBase + { + private const int PreallocatedQubitCount = 1000; + /// + /// Random number generator used for Microsoft.Quantum.Intrinsic.Random + /// + public readonly System.Random random; + + public override string Name => "QuantumExecutorSimulator"; + + /// + /// An instance of a class implementing interface that this simulator wraps. + /// + public IQuantumExecutor QuantumExecutor + { + get; + private set; + } + + /// + /// + /// + /// An instance of a class implementing interface to be wrapped. If the parameter is null is used. + /// An instance of a class implementing interface. If the parameter is null is used. + /// A seed to be used by Q# Microsoft.Quantum.Intrinsic.Random operation. + public QuantumExecutorSimulator(IQuantumExecutor quantumExecutor = null, IQubitManager qubitManager = null, int? randomSeed = null) + : base(qubitManager ?? new QubitManagerTrackingScope(PreallocatedQubitCount, mayExtendCapacity:true, disableBorrowing:false)) + { + random = new System.Random(randomSeed == null ? DateTime.Now.Millisecond : randomSeed.Value); + QuantumExecutor = quantumExecutor ?? new EmptyQuantumExecutor(); + OnOperationStart += QuantumExecutor.OnOperationStart; + OnOperationEnd += QuantumExecutor.OnOperationEnd; + OnLog += QuantumExecutor.OnMessage; + } + + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/R.cs b/src/Simulation/Simulators/QuantumExecutor/R.cs new file mode 100644 index 00000000000..e58e03f7eb1 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/R.cs @@ -0,0 +1,54 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimR : Quantum.Intrinsic.R + { + + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimR(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(Pauli, double, Qubit), QVoid> Body => (_args) => + { + + var (basis, angle, q1) = _args; + if (basis != Pauli.PauliI) + { + Simulator.QuantumExecutor.R(basis, angle,q1); + } + return QVoid.Instance; + }; + + public override Func<(Pauli, double, Qubit), QVoid> AdjointBody => (_args) => + { + var (basis, angle, q1) = _args; + return this.Body.Invoke((basis, -angle, q1)); + }; + + public override Func<(IQArray, (Pauli, double, Qubit)), QVoid> ControlledBody => (_args) => + { + + var (ctrls, (basis, angle, q1)) = _args; + Simulator.QuantumExecutor.ControlledR(ctrls, basis, angle, q1); + return QVoid.Instance; + }; + + + public override Func<(IQArray, (Pauli, double, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (basis, angle, q1)) = _args; + return this.ControlledBody.Invoke((ctrls, (basis, -angle, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/R1.cs b/src/Simulation/Simulators/QuantumExecutor/R1.cs new file mode 100644 index 00000000000..b94bd038b40 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/R1.cs @@ -0,0 +1,51 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimR1 : Quantum.Intrinsic.R1 + { + + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimR1(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit), QVoid> Body => (_args) => + { + + var (angle, q1) = _args; + Simulator.QuantumExecutor.R1(angle, q1); + return QVoid.Instance; + }; + + public override Func<(double, Qubit), QVoid> AdjointBody => (_args) => + { + var (angle, q1) = _args; + return this.Body.Invoke((-angle, q1)); + }; + + public override Func<(IQArray, ( double, Qubit)), QVoid> ControlledBody => (_args) => + { + + var (ctrls, (angle, q1)) = _args; + Simulator.QuantumExecutor.ControlledR1(ctrls, angle, q1); + return QVoid.Instance; + }; + + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (angle, q1)) = _args; + return this.ControlledBody.Invoke((ctrls, (-angle, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs b/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs new file mode 100644 index 00000000000..de2e6f4f22f --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs @@ -0,0 +1,53 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimR1Frac : Quantum.Intrinsic.R1Frac + { + + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimR1Frac(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(long, long, Qubit), QVoid> Body => (_args) => + { + + var (num, denom , q1) = _args; + var (numNew, denomNew) = CommonUtils.Reduce(num, denom); + Simulator.QuantumExecutor.R1Frac(numNew, denomNew, q1); + return QVoid.Instance; + }; + + public override Func<(long, long, Qubit), QVoid> AdjointBody => (_args) => + { + var (num, denom, q1) = _args; + return this.Body.Invoke((-num, denom, q1)); + }; + + public override Func<(IQArray, (long, long, Qubit)), QVoid> ControlledBody => (_args) => + { + + var (ctrls, (num, denom, q1)) = _args; + var (numNew, denomNew) = CommonUtils.Reduce(num, denom); + Simulator.QuantumExecutor.ControlledR1Frac(ctrls, numNew, denomNew, q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, (long, long, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (num, denom, q1)) = _args; + return this.ControlledBody.Invoke((ctrls, (-num, denom, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/RFrac.cs b/src/Simulation/Simulators/QuantumExecutor/RFrac.cs new file mode 100644 index 00000000000..27d9955154f --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/RFrac.cs @@ -0,0 +1,56 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimRFrac : Quantum.Intrinsic.RFrac + { + + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimRFrac(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(Pauli, long, long, Qubit), QVoid> Body => (_args) => + { + + var (basis, num, denom , q1) = _args; + if (basis != Pauli.PauliI) + { + var (numNew, denomNew) = CommonUtils.Reduce(num, denom); + Simulator.QuantumExecutor.RFrac(basis, numNew, denomNew, q1); + } + return QVoid.Instance; + }; + + public override Func<(Pauli, long, long, Qubit), QVoid> AdjointBody => (_args) => + { + var (basis, num, denom, q1) = _args; + return this.Body.Invoke((basis, -num, denom, q1)); + }; + + public override Func<(IQArray, (Pauli, long, long, Qubit)), QVoid> ControlledBody => (_args) => + { + + var (ctrls, (basis, num, denom, q1)) = _args; + var (numNew, denomNew) = CommonUtils.Reduce(num, denom); + Simulator.QuantumExecutor.ControlledRFrac(ctrls, basis, numNew, denomNew, q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, (Pauli, long, long, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (basis, num, denom, q1)) = _args; + return this.ControlledBody.Invoke((ctrls, (basis, -num, denom, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Release.cs b/src/Simulation/Simulators/QuantumExecutor/Release.cs new file mode 100644 index 00000000000..4447c365f86 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Release.cs @@ -0,0 +1,27 @@ +ο»Ώusing Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimRelease : Intrinsic.Release + { + private readonly QuantumExecutorSimulator sim; + public QuantumExecutorSimRelease(QuantumExecutorSimulator m) : base(m){ + sim = m; + } + + public override void Apply(Qubit q) + { + sim.QuantumExecutor.OnReleaseQubits(new QArray(q)); + sim.QubitManager.Release(q); + } + + public override void Apply(IQArray qubits) + { + sim.QuantumExecutor.OnReleaseQubits(qubits); + sim.QubitManager.Release(qubits); + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/Reset.cs b/src/Simulation/Simulators/QuantumExecutor/Reset.cs new file mode 100644 index 00000000000..6c655d06e1b --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Reset.cs @@ -0,0 +1,27 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimReset : Quantum.Intrinsic.Reset + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimReset(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.Reset(q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Return.cs b/src/Simulation/Simulators/QuantumExecutor/Return.cs new file mode 100644 index 00000000000..cdeeb859aa6 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Return.cs @@ -0,0 +1,27 @@ +ο»Ώnamespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + using Microsoft.Quantum.Simulation.Core; + + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimReturn : Intrinsic.Return + { + private readonly QuantumExecutorSimulator sim; + public QuantumExecutorSimReturn(QuantumExecutorSimulator m) : base(m){ + sim = m; + } + + public override void Apply(Qubit q) + { + sim.QuantumExecutor.OnReturnQubits(new QArray(q)); + sim.QubitManager.Return(q); + } + + public override void Apply(IQArray qubits) + { + sim.QuantumExecutor.OnReturnQubits(qubits); + sim.QubitManager.Return(qubits); + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/S.cs b/src/Simulation/Simulators/QuantumExecutor/S.cs new file mode 100644 index 00000000000..510867fd758 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/S.cs @@ -0,0 +1,49 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimS : Quantum.Intrinsic.S + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimS(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.S(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + Simulator.QuantumExecutor.ControlledS(ctrls, q1); + return QVoid.Instance; + }; + + public override Func AdjointBody => (q1) => + { + + Simulator.QuantumExecutor.SAdj(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + Simulator.QuantumExecutor.ControlledSAdj(ctrls, q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/SWAP.cs b/src/Simulation/Simulators/QuantumExecutor/SWAP.cs new file mode 100644 index 00000000000..8aeb05eefdc --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/SWAP.cs @@ -0,0 +1,35 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimSWAP : Quantum.Intrinsic.SWAP + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimSWAP(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(Qubit,Qubit), QVoid> Body => (q1) => + { + + Simulator.QuantumExecutor.SWAP(q1.Item1, q1.Item2); + return QVoid.Instance; + }; + + public override Func<(IQArray, (Qubit, Qubit)), QVoid> ControlledBody => (args) => + { + + var (ctrls, q1) = args; + Simulator.QuantumExecutor.ControlledSWAP(ctrls, q1.Item1, q1.Item2); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/T.cs b/src/Simulation/Simulators/QuantumExecutor/T.cs new file mode 100644 index 00000000000..06e650b6056 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/T.cs @@ -0,0 +1,52 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimT : Quantum.Intrinsic.T + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimT(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.T(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + + Simulator.QuantumExecutor.ControlledT(ctrls, q1); + + return QVoid.Instance; + }; + + public override Func AdjointBody => (q1) => + { + + Simulator.QuantumExecutor.TAdj(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + Simulator.QuantumExecutor.ControlledTAdj(ctrls, q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/X.cs b/src/Simulation/Simulators/QuantumExecutor/X.cs new file mode 100644 index 00000000000..4bcb59e4f5b --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/X.cs @@ -0,0 +1,35 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimX : Quantum.Intrinsic.X + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimX(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.X(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (args) => + { + + var (ctrls, q1) = args; + Simulator.QuantumExecutor.ControlledX(ctrls, q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Y.cs b/src/Simulation/Simulators/QuantumExecutor/Y.cs new file mode 100644 index 00000000000..89e37c6f1a1 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Y.cs @@ -0,0 +1,35 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimY : Quantum.Intrinsic.Y + { + private QuantumExecutorSimulator Simulator { get; } + + + public QuantumExecutorSimY(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.Y(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + Simulator.QuantumExecutor.ControlledY(ctrls, q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Z.cs b/src/Simulation/Simulators/QuantumExecutor/Z.cs new file mode 100644 index 00000000000..8a37d2999b3 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/Z.cs @@ -0,0 +1,35 @@ +ο»Ώusing System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Intrinsic; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public class QuantumExecutorSimZ : Quantum.Intrinsic.Z + { + private QuantumExecutorSimulator Simulator { get; } + + public QuantumExecutorSimZ(QuantumExecutorSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + + Simulator.QuantumExecutor.Z(q1); + return QVoid.Instance; + }; + + public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => + { + + (IQArray ctrls, Qubit q1) = _args; + Simulator.QuantumExecutor.ControlledZ(ctrls, q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/random.cs b/src/Simulation/Simulators/QuantumExecutor/random.cs new file mode 100644 index 00000000000..4f10b3a1e68 --- /dev/null +++ b/src/Simulation/Simulators/QuantumExecutor/random.cs @@ -0,0 +1,52 @@ +ο»Ώusing Microsoft.Quantum.Simulation.Core; +using System; + +namespace Microsoft.Quantum.Simulation.QuantumExecutor +{ + public partial class QuantumExecutorSimulator + { + public static long SampleDistribution(IQArray unnormalizedDistribution, double uniformZeroOneSample) + { + double total = 0.0; + foreach (double prob in unnormalizedDistribution) + { + if (prob < 0) + { + throw new ExecutionFailException("Random expects array of non-negative doubles."); + } + total += prob; + } + + if (total == 0) + { + throw new ExecutionFailException("Random expects array of non-negative doubles with positive sum."); + } + + double sample = uniformZeroOneSample * total; + double sum = unnormalizedDistribution[0]; + for (int i = 0; i < unnormalizedDistribution.Length - 1; ++i) + { + if (sum >= sample) + { + return i; + } + sum += unnormalizedDistribution[i]; + } + return unnormalizedDistribution.Length; + } + + public class QuantumExecutorSimRandom : Quantum.Intrinsic.Random + { + private QuantumExecutorSimulator Simulator { get; } + public QuantumExecutorSimRandom(QuantumExecutorSimulator m) : base(m) + { + Simulator = m; + } + + public override Func, Int64> Body => (p) => + { + return SampleDistribution(p, Simulator.random.NextDouble()); + }; + } + } +} From a981506fa614c17c356f2c4f6c43411130ccfce2 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Thu, 31 Oct 2019 17:11:58 -0700 Subject: [PATCH 02/12] Classical control --- src/Simulation/Common/IQuantumExecutor.cs | 330 +++++++++--------- src/Simulation/Common/Utils.cs | 5 +- .../Simulators/QuantumExecutor/Allocate.cs | 5 +- .../Simulators/QuantumExecutor/Assert.cs | 6 +- .../Simulators/QuantumExecutor/AssertProb.cs | 6 +- .../Simulators/QuantumExecutor/Borrow.cs | 5 +- .../QuantumExecutor/ClassicalControl.cs | 130 ++++++- .../QuantumExecutor/ClassicalControl.qs | 171 +++++---- .../Simulators/QuantumExecutor/Dump.cs | 7 +- .../QuantumExecutor/EmptyQuantumExecutor.cs | 12 +- .../Simulators/QuantumExecutor/Exp.cs | 8 +- .../Simulators/QuantumExecutor/ExpFrac.cs | 6 +- .../Simulators/QuantumExecutor/H.cs | 6 +- .../Simulators/QuantumExecutor/M.cs | 8 +- .../Simulators/QuantumExecutor/Measure.cs | 7 +- .../QuantumExecutorSimulator.cs | 4 +- .../Simulators/QuantumExecutor/R.cs | 6 +- .../Simulators/QuantumExecutor/R1.cs | 6 +- .../Simulators/QuantumExecutor/R1Frac.cs | 6 +- .../Simulators/QuantumExecutor/RFrac.cs | 6 +- .../Simulators/QuantumExecutor/Release.cs | 5 +- .../Simulators/QuantumExecutor/Reset.cs | 6 +- .../Simulators/QuantumExecutor/Return.cs | 5 +- .../Simulators/QuantumExecutor/S.cs | 6 +- .../Simulators/QuantumExecutor/SWAP.cs | 6 +- .../Simulators/QuantumExecutor/T.cs | 6 +- .../Simulators/QuantumExecutor/X.cs | 6 +- .../Simulators/QuantumExecutor/Y.cs | 6 +- .../Simulators/QuantumExecutor/Z.cs | 7 +- .../Simulators/QuantumExecutor/random.cs | 5 +- 30 files changed, 519 insertions(+), 279 deletions(-) diff --git a/src/Simulation/Common/IQuantumExecutor.cs b/src/Simulation/Common/IQuantumExecutor.cs index 935a217ed75..09c0c018e02 100644 --- a/src/Simulation/Common/IQuantumExecutor.cs +++ b/src/Simulation/Common/IQuantumExecutor.cs @@ -1,4 +1,7 @@ -ο»Ώusing System; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor @@ -15,116 +18,98 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor public interface IQuantumExecutor { /// - /// Called when Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to . + /// Called when Microsoft.Quantum.Intrinsic.X is called in Q#. + /// In Q# the operation applies X gate to . The gate is given by matrix X=((0,1),(1,0)). /// /// - /// When adjoint of R is called in Q#, is called with replaced by -. + /// When adjoint of X is called in Q#, is called because X is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Pauli operator to be exponentiated to form the rotation. - /// Angle about which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void R(Pauli axis, double theta, Qubit qubit); + void X(Qubit qubit); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to controlled on . + /// Called when controlled Microsoft.Quantum.Intrinsic.X is called in Q#. + /// In Q# the operation applies X gate to controlled on . The gate is given by matrix X=((0,1),(1,0)). /// /// - /// When adjoint of Controlled R is called in Q#, is called with replaced by -. + /// When adjoint of Controlled X is called in Q#, is called because X is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Pauli operator to be exponentiated to form the rotation. - /// Angle about which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit); + void ControlledX(IQArray controls, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.RFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// Called when Microsoft.Quantum.Intrinsic.Y is called in Q#. + /// In Q# the operation applies Y gate to . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// - /// When adjoint of RFrac is called in Q#, is called with replaced by -. + /// When adjoint of Y is called in Q#, is called because Y is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Pauli operator to be exponentiated to form the rotation. - /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void RFrac(Pauli axis, long numerator, long power, Qubit qubit); + void Y(Qubit qubit); /// - /// Called when a controlled Microsoft.Quantum.Intrinsic.RFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// Called when controlled Microsoft.Quantum.Intrinsic.Y is called in Q#. + /// In Q# the operation applies X gate to controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// - /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. + /// When adjoint of Controlled Y is called in Q#, is called because Y is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Pauli operator to be exponentiated to form the rotation. - /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit); + void ControlledY(IQArray controls, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Exp is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to . + /// Called when Microsoft.Quantum.Intrinsic.Z is called in Q#. + /// In Q# the operation applies Z gate to . The gate is given by matrix Z=((1,0),(0,-1)). /// /// - /// When adjoint of Exp is called in Q#, is called with replaced by -. + /// When adjoint of Z is called in Q#, is called because Z is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. - /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. - /// Register to apply the exponent to. - void Exp(IQArray paulis, double theta, IQArray qubits); + /// Qubit to which the gate should be applied. + void Z(Qubit qubit); /// - /// Called when a controlled Microsoft.Quantum.Intrinsic.Exp is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to controlled on . + /// Called when controlled Microsoft.Quantum.Intrinsic.Z is called in Q#. + /// In Q# the operation applies Z gate to controlled on . The gate is given by matrix Z=((1,0),(0,-1)). /// /// - /// When adjoint of Controlled Exp is called in Q#, is called with replaced by -. + /// When adjoint of Controlled Z is called in Q#, is called because Z is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. - /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. - /// Register to apply the exponent to. - void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits); + /// Qubit to which the gate should be applied. + void ControlledZ(IQArray controls, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// Called when Microsoft.Quantum.Intrinsic.SWAP is called in Q#. + /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states. /// /// - /// When adjoint of ExpFrac is called in Q#, is called with replaced by -. + /// When adjoint of SWAP is called in Q#, is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. - /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. - /// Register to apply the exponent to. - void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits); + /// First qubit to be swapped. + /// Second qubit to be swapped. + void SWAP(Qubit qubit1, Qubit qubit2); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// Called when controlled Microsoft.Quantum.Intrinsic.SWAP is called in Q#. + /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states controlled on . /// /// - /// When adjoint of Controlled ExpFrac is called in Q#, is called with replaced by -. + /// When adjoint of Controlled SWAP is called in Q#, is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. - /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. - /// Register to apply the exponent to. - void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits); + /// First qubit to be swapped. + /// Second qubit to be swapped. + void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2); /// /// Called when Microsoft.Quantum.Intrinsic.H is called in Q#. @@ -211,7 +196,7 @@ public interface IQuantumExecutor /// In Q# the operation applies T gate to controlled on . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). /// /// - /// When adjoint of Controlled T is called in Q#, is called. + /// When adjoint of Controlled T is called in Q#, is called. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -242,210 +227,228 @@ public interface IQuantumExecutor void ControlledTAdj(IQArray controls, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.M is called in Q#. - /// In Q# the operation measures in Z basis, in other words in the computational basis. + /// Called when Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to . /// /// + /// When adjoint of R is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. - /// Class implementing interface can return any class derived from . /// + /// Pauli operator to be exponentiated to form the rotation. + /// Angle about which the qubit is to be rotated. /// Qubit to which the gate should be applied. - /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. - Result M(Qubit qubit); + void R(Pauli axis, double theta, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Measure is called in Q#. - /// In Q# the operation measures multi-qubit Pauli observable given by on . + /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to controlled on . /// /// + /// When adjoint of Controlled R is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. - /// Class implementing interface can return any class derived from . /// - /// Qubits to which the gate should be applied. - /// Array of single-qubit Pauli values describing multi-qubit Pauli observable. - /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. - Result Measure(IQArray bases, IQArray qubits); + /// The array of qubits on which the operation is controlled. + /// Pauli operator to be exponentiated to form the rotation. + /// Angle about which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Reset is called in Q#. - /// In Q# the operation, measures and ensures it is in the |0⟩ state such that it can be safely released. + /// Called when Microsoft.Quantum.Intrinsic.RFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . /// /// + /// When adjoint of RFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// + /// Pauli operator to be exponentiated to form the rotation. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void Reset(Qubit qubit); + void RFrac(Pauli axis, long numerator, long power, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// Called when a controlled Microsoft.Quantum.Intrinsic.RFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . /// /// + /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. - /// A register on which to make the assertion. - /// The expected result of Measure(bases, qubits) - /// A message to be reported if the assertion fails. - void Assert(IQArray bases, IQArray qubits, Result result, string msg); - - /// - /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. - /// - /// - /// The names and the order of the parameters is similar to the corresponding Q# operation./ - /// - /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. - /// A register on which to make the assertion. - /// The probability with which result Zero is expected. - /// A message to be reported if the assertion fails. - /// The precision with which the probability of Zero outcome is specified. - void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol); + /// The array of qubits on which the operation is controlled. + /// Pauli operator to be exponentiated to form the rotation. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. + /// Qubit to which the gate should be applied. + void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.X is called in Q#. - /// In Q# the operation applies X gate to . The gate is given by matrix X=((0,1),(1,0)). + /// Called when Microsoft.Quantum.Intrinsic.R1 is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to . /// /// - /// When adjoint of X is called in Q#, is called because X is self-adjoint. + /// When adjoint of R1 is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// + /// Angle about which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void X(Qubit qubit); + void R1(double theta, Qubit qubit); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.X is called in Q#. - /// In Q# the operation applies X gate to controlled on . The gate is given by matrix X=((0,1),(1,0)). + /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to controlled on . /// /// - /// When adjoint of Controlled X is called in Q#, is called because X is self-adjoint. + /// When adjoint of Controlled R1 is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. + /// Angle about which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void ControlledX(IQArray controls, Qubit qubit); + void ControlledR1(IQArray controls, double theta, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Y is called in Q#. - /// In Q# the operation applies Y gate to . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// Called when Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to . /// /// - /// When adjoint of Y is called in Q#, is called because Y is self-adjoint. + /// When adjoint of R1Frac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void Y(Qubit qubit); + void R1Frac(long numerator, long power, Qubit qubit); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.Y is called in Q#. - /// In Q# the operation applies X gate to controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// Called when a controlled Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. + /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to controlled on . /// /// - /// When adjoint of Controlled Y is called in Q#, is called because Y is self-adjoint. + /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. + /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void ControlledY(IQArray controls, Qubit qubit); + void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit); /// - /// Called when Microsoft.Quantum.Intrinsic.Z is called in Q#. - /// In Q# the operation applies Z gate to . The gate is given by matrix Z=((1,0),(0,-1)). + /// Called when Microsoft.Quantum.Intrinsic.Exp is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to . /// /// - /// When adjoint of Z is called in Q#, is called because Z is self-adjoint. + /// When adjoint of Exp is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Qubit to which the gate should be applied. - void Z(Qubit qubit); + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. + /// Register to apply the exponent to. + void Exp(IQArray paulis, double theta, IQArray qubits); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.Z is called in Q#. - /// In Q# the operation applies Z gate to controlled on . The gate is given by matrix Z=((1,0),(0,-1)). + /// Called when a controlled Microsoft.Quantum.Intrinsic.Exp is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to controlled on . /// /// - /// When adjoint of Controlled Z is called in Q#, is called because Z is self-adjoint. + /// When adjoint of Controlled Exp is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Qubit to which the gate should be applied. - void ControlledZ(IQArray controls, Qubit qubit); + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Angle about the given multi-qubit Pauli operator by which the target register is to be rotated. + /// Register to apply the exponent to. + void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits); /// - /// Called when Microsoft.Quantum.Intrinsic.R1 is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to . + /// Called when Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . /// /// - /// When adjoint of R1 is called in Q#, is called with replaced by -. + /// When adjoint of ExpFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// Angle about which the qubit is to be rotated. - /// Qubit to which the gate should be applied. - void R1(double theta, Qubit qubit); + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. + /// Register to apply the exponent to. + void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to controlled on . + /// Called when controlled Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. + /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . /// /// - /// When adjoint of Controlled R1 is called in Q#, is called with replaced by -. + /// When adjoint of Controlled ExpFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. - /// Angle about which the qubit is to be rotated. - /// Qubit to which the gate should be applied. - void ControlledR1(IQArray controls, double theta, Qubit qubit); + /// Array of single-qubit Pauli values representing a multi-qubit Pauli to be applied. + /// Numerator in the dyadic fraction representation of the angle by which the qubit register is to be rotated. + /// Power of two specifying the denominator of the angle by which the qubit register is to be rotated. + /// Register to apply the exponent to. + void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits); /// - /// Called when Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to . + /// Called when Microsoft.Quantum.Intrinsic.M is called in Q#. + /// In Q# the operation measures in Z basis, in other words in the computational basis. /// /// - /// When adjoint of R1Frac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// Class implementing interface can return any class derived from . /// - /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. /// Qubit to which the gate should be applied. - void R1Frac(long numerator, long power, Qubit qubit); + /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. + Result M(Qubit qubit); /// - /// Called when a controlled Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to controlled on . + /// Called when Microsoft.Quantum.Intrinsic.Measure is called in Q#. + /// In Q# the operation measures multi-qubit Pauli observable given by on . /// /// - /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. /// The names and the order of the parameters are the same as for the corresponding Q# operation. + /// Class implementing interface can return any class derived from . /// - /// The array of qubits on which the operation is controlled. - /// Numerator in the dyadic fraction representation of the angle by which the qubit is to be rotated. - /// Power of two specifying the denominator of the angle by which the qubit is to be rotated. - /// Qubit to which the gate should be applied. - void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit); + /// Qubits to which the gate should be applied. + /// Array of single-qubit Pauli values describing multi-qubit Pauli observable. + /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. + Result Measure(IQArray bases, IQArray qubits); /// - /// Called when Microsoft.Quantum.Intrinsic.SWAP is called in Q#. - /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states. + /// Called when Microsoft.Quantum.Intrinsic.Reset is called in Q#. + /// In Q# the operation, measures and ensures it is in the |0⟩ state such that it can be safely released. /// /// - /// When adjoint of SWAP is called in Q#, is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// First qubit to be swapped. - /// Second qubit to be swapped. - void SWAP(Qubit qubit1, Qubit qubit2); + /// Qubit to which the gate should be applied. + void Reset(Qubit qubit); /// - /// Called when controlled Microsoft.Quantum.Intrinsic.SWAP is called in Q#. - /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states controlled on . + /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. /// /// - /// When adjoint of Controlled SWAP is called in Q#, is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// - /// The array of qubits on which the operation is controlled. - /// First qubit to be swapped. - /// Second qubit to be swapped. - void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2); + /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. + /// A register on which to make the assertion. + /// The expected result of Measure(bases, qubits) + /// A message to be reported if the assertion fails. + void Assert(IQArray bases, IQArray qubits, Result result, string msg); + + /// + /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// + /// + /// The names and the order of the parameters is similar to the corresponding Q# operation./ + /// + /// A multi-qubit Pauli operator, for which the measurement outcome is asserted. + /// A register on which to make the assertion. + /// The probability with which result Zero is expected. + /// A message to be reported if the assertion fails. + /// The precision with which the probability of Zero outcome is specified. + void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol); /// /// Called before a call to any Q# operation. @@ -491,6 +494,19 @@ public interface IQuantumExecutor /// void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); + /// + /// Intended for a limited support of branching upon measurement results on a simulator level. + /// + /// The actual results of the measurements of a number of qubits upon which branching is to be performed. + /// The expected values of results of the measurements of these qubits. + /// Corresponds to quantum program that must be executed if all values are equal to corresponding + /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding + /// + /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . + /// The program is executed with the same instance of interface. + /// + void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); + /// /// Called when qubits are allocated by Q# using block. /// diff --git a/src/Simulation/Common/Utils.cs b/src/Simulation/Common/Utils.cs index 6850ad7975d..04df6315d59 100644 --- a/src/Simulation/Common/Utils.cs +++ b/src/Simulation/Common/Utils.cs @@ -1,6 +1,7 @@ -ο»Ώusing Microsoft.Quantum.Intrinsic; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using Microsoft.Quantum.Simulation.Core; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/Simulation/Simulators/QuantumExecutor/Allocate.cs b/src/Simulation/Simulators/QuantumExecutor/Allocate.cs index 5f8c9c336ac..04ceba85113 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Allocate.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Allocate.cs @@ -1,4 +1,7 @@ -ο»Ώusing Microsoft.Quantum.Simulation.Core; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor { diff --git a/src/Simulation/Simulators/QuantumExecutor/Assert.cs b/src/Simulation/Simulators/QuantumExecutor/Assert.cs index fef0b748262..64450284bb3 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Assert.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Assert.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Collections.Generic; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs b/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs index da8446aa8c8..1b283a44804 100644 --- a/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs +++ b/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Collections.Generic; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/Borrow.cs b/src/Simulation/Simulators/QuantumExecutor/Borrow.cs index 82d5062a4f1..0dbfe80e838 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Borrow.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Borrow.cs @@ -1,4 +1,7 @@ -ο»Ώusing Microsoft.Quantum.Simulation.Core; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor { diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs index 11eb7bf8ac8..fee486af63f 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs +++ b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs @@ -1,7 +1,7 @@ -ο»Ώusing System; -using System.Diagnostics; -using System.Linq; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor @@ -112,5 +112,127 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA return QVoid.Instance; }; } + + + + + + + + + + + + public class SimApplyConditionally : Extensions.ApplyConditionallyIntrinsic + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyConditionally(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(IQArray, IQArray, ICallable, ICallable), QVoid> Body => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Apply(QVoid.Instance), + () => onNonEqualOp.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + } + + public class SimApplyConditionallyA : Extensions.ApplyConditionallyIntrinsicA + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyConditionallyA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> Body => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Apply(QVoid.Instance), + () => onNonEqualOp.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Adjoint.Apply(QVoid.Instance), + () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + } + + public class SimApplyConditionallyC : Extensions.ApplyConditionallyIntrinsicC + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyConditionallyC(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Apply(QVoid.Instance), + () => onNonEqualOp.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => //(q) => + (q) => + { + var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Controlled.Apply(ctrls), + () => onNonEqualOp.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; + } + + public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA + { + private QuantumExecutorSimulator Simulator { get; } + + public SimApplyConditionallyCA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + + public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Apply(QVoid.Instance), + () => onNonEqualOp.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> AdjointBody => (q) => + { + var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Adjoint.Apply(QVoid.Instance), + () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => + { + var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Controlled.Apply(ctrls), + () => onNonEqualOp.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; + + public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => //(q) => + (q) => + { + var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Controlled.Adjoint.Apply(ctrls), + () => onNonEqualOp.Controlled.Adjoint.Apply(ctrls)); + return QVoid.Instance; + }; + } + } } diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs index 07bda4eb33c..f98b6e23c3a 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs +++ b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs @@ -1,41 +1,67 @@ -ο»Ώnamespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions { open Microsoft.Quantum.Intrinsic; operation NoOp() : Unit is Ctl + Adj {} - operation Delay<'T> ( op : ('T => Unit), arg : 'T, aux : Unit ) : Unit { + + operation Delay<'T>(op : ('T => Unit), arg : 'T, aux : Unit) : Unit { op(arg); } - operation DelayC<'T> ( op : ('T => Unit is Ctl), arg : 'T, aux : Unit ) : Unit is Ctl { + operation DelayC<'T>(op : ('T => Unit is Ctl), arg : 'T, aux : Unit) : Unit is Ctl { op(arg); } - operation DelayA<'T> ( op : ('T => Unit is Adj), arg : 'T, aux : Unit ) : Unit is Adj { + operation DelayA<'T>(op : ('T => Unit is Adj), arg : 'T, aux : Unit) : Unit is Adj { op(arg); } - operation DelayCA<'T> ( op : ('T => Unit is Ctl + Adj), arg : 'T, aux : Unit ) : Unit is Ctl + Adj { + operation DelayCA<'T>(op : ('T => Unit is Ctl + Adj), arg : 'T, aux : Unit) : Unit is Ctl + Adj { op(arg); } - operation ApplyIfElseIntrinsic( measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit) ) : Unit { + operation ApplyIfElseIntrinsic(measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit)) : Unit { + body intrinsic; + } + + operation ApplyIfElseIntrinsicA(measurementResult : Result, onResultZeroOp : (Unit => Unit is Adj) , onResultOneOp : (Unit => Unit is Adj)) : Unit { + body intrinsic; + adjoint intrinsic; + } + + operation ApplyIfElseIntrinsicC(measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl) , onResultOneOp : (Unit => Unit is Ctl)) : Unit { + body intrinsic; + controlled intrinsic; + } + + operation ApplyIfElseIntrinsicCA(measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl + Adj) , onResultOneOp : (Unit => Unit is Ctl + Adj)) : Unit { + body intrinsic; + adjoint intrinsic; + controlled intrinsic; + controlled adjoint intrinsic; + } + + + operation ApplyConditionallyIntrinsic(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit) , onNonEqualOp : (Unit => Unit)) : Unit { body intrinsic; } - operation ApplyIfElseIntrinsicA( measurementResult : Result, onResultZeroOp : (Unit => Unit is Adj) , onResultOneOp : (Unit => Unit is Adj) ) : Unit { + operation ApplyConditionallyIntrinsicA(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Adj) , onNonEqualOp : (Unit => Unit is Adj)) : Unit is Adj { body intrinsic; adjoint intrinsic; } - operation ApplyIfElseIntrinsicC( measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl) , onResultOneOp : (Unit => Unit is Ctl) ) : Unit { + operation ApplyConditionallyIntrinsicC(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl) , onNonEqualOp : (Unit => Unit is Ctl)) : Unit is Ctl { body intrinsic; controlled intrinsic; } - operation ApplyIfElseIntrinsicCA( measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl + Adj) , onResultOneOp : (Unit => Unit is Ctl + Adj) ) : Unit { + operation ApplyConditionallyIntrinsicCA(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl + Adj) , onNonEqualOp : (Unit => Unit is Ctl + Adj)) : Unit is Ctl + Adj { body intrinsic; adjoint intrinsic; controlled intrinsic; @@ -43,82 +69,103 @@ } - operation ApplyIfElse<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) , (onResultOneOp : ('U => Unit), oneArg : 'U) ) : Unit { - let zeroOp = Delay(onResultZeroOp,zeroArg,_); - let oneOp = Delay(onResultOneOp,oneArg,_); - ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + operation ApplyIfElseR<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) , (onResultOneOp : ('U => Unit), oneArg : 'U)) : Unit { + let zeroOp = Delay(onResultZeroOp, zeroArg, _); + let oneOp = Delay(onResultOneOp, oneArg, _); + ApplyIfElseIntrinsic(measurementResult, zeroOp, oneOp); } -// operation ApplyIfElseArray<'T,'U>( measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit), equalArg : 'T) , (onNonEqualOp : ('U => Unit), nonEqualArg : 'U) ) : Unit { -// let equalOp = Delay(onEqualOp,equalArg,_); -// let nonEqualOp = Delay(onNonEqualOp,nonEqualArg,_); // normalize spaces !!! -// //ApplyIfElseIntrinsic( measurementResults, resultsValues, equalOp, nonEqualOp ); // wrong!!! -// } + operation ApplyIfElseRA<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj), oneArg : 'U)) : Unit is Adj { + let zeroOp = DelayA(onResultZeroOp, zeroArg, _); + let oneOp = DelayA(onResultOneOp, oneArg, _); + ApplyIfElseIntrinsicA(measurementResult, zeroOp, oneOp); + } - operation ApplyIfElseA<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj), oneArg : 'U) ) : Unit is Adj { - let zeroOp = DelayA(onResultZeroOp,zeroArg,_); - let oneOp = DelayA(onResultOneOp,oneArg,_); - ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + operation ApplyIfElseRC<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Ctl), oneArg : 'U)) : Unit is Ctl { + let zeroOp = DelayC(onResultZeroOp, zeroArg, _); + let oneOp = DelayC(onResultOneOp, oneArg, _); + ApplyIfElseIntrinsicC(measurementResult, zeroOp, oneOp); } - operation ApplyIfElseC<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Ctl), oneArg : 'U) ) : Unit is Ctl { - let zeroOp = DelayC(onResultZeroOp,zeroArg,_); - let oneOp = DelayC(onResultOneOp,oneArg,_); - ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + operation ApplyIfElseCA<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj + Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj + Ctl), oneArg : 'U)) : Unit is Ctl + Adj { + let zeroOp = DelayCA(onResultZeroOp, zeroArg, _); + let oneOp = DelayCA(onResultOneOp, oneArg, _); + ApplyIfElseIntrinsicCA(measurementResult, zeroOp, oneOp); } - operation ApplyIfElseCA<'T,'U>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj + Ctl), zeroArg : 'T) , (onResultOneOp : ('U => Unit is Adj + Ctl), oneArg : 'U) ) : Unit is Ctl + Adj { - let zeroOp = DelayCA(onResultZeroOp,zeroArg,_); - let oneOp = DelayCA(onResultOneOp,oneArg,_); - ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + + operation ApplyIfZero<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T)) : Unit { + let zeroOp = Delay(onResultZeroOp, zeroArg, _); + let oneOp = Delay(NoOp, (), _); + ApplyIfElseIntrinsic(measurementResult, zeroOp, oneOp); } - operation ApplyIfZero<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) ) : Unit { - let zeroOp = Delay(onResultZeroOp,zeroArg,_); - let oneOp = Delay(NoOp, (),_); - ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + operation ApplyIfZeroA<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T)) : Unit is Adj{ + let zeroOp = DelayA(onResultZeroOp, zeroArg, _); + let oneOp = DelayA(NoOp, (), _); + ApplyIfElseIntrinsicA(measurementResult, zeroOp, oneOp); } - operation ApplyIfZeroA<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Adj), zeroArg : 'T) ) : Unit is Adj{ - let zeroOp = DelayA(onResultZeroOp,zeroArg,_); - let oneOp = DelayA(NoOp, (),_); - ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + operation ApplyIfZeroC<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T)) : Unit is Ctl { + let zeroOp = DelayC(onResultZeroOp, zeroArg, _); + let oneOp = DelayC(NoOp, (), _); + ApplyIfElseIntrinsicC(measurementResult, zeroOp, oneOp); } - operation ApplyIfZeroC<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl), zeroArg : 'T) ) : Unit is Ctl { - let zeroOp = DelayC(onResultZeroOp,zeroArg,_); - let oneOp = DelayC(NoOp, (),_); - ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + operation ApplyIfZeroCA<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl + Adj), zeroArg : 'T)) : Unit is Ctl + Adj { + let zeroOp = DelayCA(onResultZeroOp, zeroArg, _); + let oneOp = DelayCA(NoOp, (), _); + ApplyIfElseIntrinsicCA(measurementResult, zeroOp, oneOp); } - operation ApplyIfZeroCA<'T>( measurementResult : Result, (onResultZeroOp : ('T => Unit is Ctl + Adj), zeroArg : 'T) ) : Unit is Ctl + Adj { - let zeroOp = DelayCA(onResultZeroOp,zeroArg,_); - let oneOp = DelayCA(NoOp, (),_); - ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + + operation ApplyIfOne<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit), oneArg : 'T)) : Unit { + let oneOp = Delay(onResultOneOp, oneArg, _); + let zeroOp = Delay(NoOp, (), _); + ApplyIfElseIntrinsic(measurementResult, zeroOp, oneOp); } - operation ApplyIfOne<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit), oneArg : 'T) ) : Unit { - let oneOp = Delay(onResultOneOp,oneArg,_); - let zeroOp = Delay(NoOp, (),_); - ApplyIfElseIntrinsic( measurementResult, zeroOp, oneOp ); + operation ApplyIfOneA<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit is Adj), oneArg : 'T)) : Unit is Adj { + let oneOp = DelayA(onResultOneOp, oneArg, _); + let zeroOp = DelayA(NoOp, (), _); + ApplyIfElseIntrinsicA(measurementResult, zeroOp, oneOp); + } + + operation ApplyIfOneC<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl), oneArg : 'T)) : Unit is Ctl { + let oneOp = DelayC(onResultOneOp, oneArg, _); + let zeroOp = DelayC(NoOp, (), _); + ApplyIfElseIntrinsicC(measurementResult, zeroOp, oneOp); + } + + operation ApplyIfOneCA<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl + Adj), oneArg : 'T)) : Unit is Ctl + Adj { + let oneOp = DelayCA(onResultOneOp, oneArg, _); + let zeroOp = DelayCA(NoOp, (), _); + ApplyIfElseIntrinsicCA(measurementResult, zeroOp, oneOp); + } + + + operation ApplyConditionally<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit), equalArg : 'T) , (onNonEqualOp : ('U => Unit), nonEqualArg : 'U)) : Unit { + let equalOp = Delay(onEqualOp,equalArg,_); + let nonEqualOp = Delay(onNonEqualOp,nonEqualArg,_); + ApplyConditionallyIntrinsic(measurementResults, resultsValues, equalOp, nonEqualOp); } - operation ApplyIfOneA<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Adj), oneArg : 'T) ) : Unit is Adj { - let oneOp = DelayA(onResultOneOp,oneArg,_); - let zeroOp = DelayA(NoOp, (),_); - ApplyIfElseIntrinsicA( measurementResult, zeroOp, oneOp ); + operation ApplyConditionallyA<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit is Adj), equalArg : 'T) , (onNonEqualOp : ('U => Unit is Adj), nonEqualArg : 'U)) : Unit is Adj { + let equalOp = DelayA(onEqualOp, equalArg, _); + let nonEqualOp = DelayA(onNonEqualOp, nonEqualArg, _); + ApplyConditionallyIntrinsicA(measurementResults, resultsValues, equalOp, nonEqualOp); } - operation ApplyIfOneC<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl), oneArg : 'T) ) : Unit is Ctl { - let oneOp = DelayC(onResultOneOp,oneArg,_); - let zeroOp = DelayC(NoOp, (),_); - ApplyIfElseIntrinsicC( measurementResult, zeroOp, oneOp ); + operation ApplyConditionallyC<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit is Ctl), equalArg : 'T) , (onNonEqualOp : ('U => Unit is Ctl), nonEqualArg : 'U)) : Unit is Ctl { + let equalOp = DelayC(onEqualOp, equalArg, _); + let nonEqualOp = DelayC(onNonEqualOp, nonEqualArg, _); + ApplyConditionallyIntrinsicC(measurementResults, resultsValues, equalOp, nonEqualOp); } - operation ApplyIfOneCA<'T>( measurementResult : Result, (onResultOneOp : ('T => Unit is Ctl + Adj), oneArg : 'T) ) : Unit is Ctl + Adj { - let oneOp = DelayCA(onResultOneOp,oneArg,_); - let zeroOp = DelayCA(NoOp, (),_); - ApplyIfElseIntrinsicCA( measurementResult, zeroOp, oneOp ); + operation ApplyConditionallyCA<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit is Ctl + Adj), equalArg : 'T) , (onNonEqualOp : ('U => Unit is Ctl + Adj), nonEqualArg : 'U)) : Unit is Ctl + Adj { + let equalOp = DelayCA(onEqualOp, equalArg, _); + let nonEqualOp = DelayCA(onNonEqualOp, nonEqualArg, _); + ApplyConditionallyIntrinsicCA(measurementResults, resultsValues, equalOp, nonEqualOp); } } diff --git a/src/Simulation/Simulators/QuantumExecutor/Dump.cs b/src/Simulation/Simulators/QuantumExecutor/Dump.cs index ce7c997051a..749631d9f90 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Dump.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Dump.cs @@ -1,6 +1,7 @@ -ο»Ώusing System; -using System.IO; -using System.Linq; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs index fc8636c69f7..ae88f95835d 100644 --- a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs +++ b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs @@ -1,6 +1,7 @@ -ο»Ώusing System; -using System.Collections.Generic; -using System.Text; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor @@ -23,6 +24,11 @@ public virtual void ClassicallyControlled(Result measurementResult, Action onZer throw new NotImplementedException(); } + public virtual void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp) + { + throw new NotImplementedException(); + } + public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) { throw new NotImplementedException(); diff --git a/src/Simulation/Simulators/QuantumExecutor/Exp.cs b/src/Simulation/Simulators/QuantumExecutor/Exp.cs index e809f9dce13..6d8469dd46b 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Exp.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Exp.cs @@ -1,7 +1,7 @@ -ο»Ώusing System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs b/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs index 7407a42ab99..865f4b3bc7b 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs +++ b/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs @@ -1,7 +1,9 @@ -ο»Ώusing Microsoft.Quantum.Simulation.Common; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; using System; -using System.Collections.Generic; namespace Microsoft.Quantum.Simulation.QuantumExecutor { diff --git a/src/Simulation/Simulators/QuantumExecutor/H.cs b/src/Simulation/Simulators/QuantumExecutor/H.cs index bea3fee8920..8cbd721019c 100644 --- a/src/Simulation/Simulators/QuantumExecutor/H.cs +++ b/src/Simulation/Simulators/QuantumExecutor/H.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/M.cs b/src/Simulation/Simulators/QuantumExecutor/M.cs index 573ddc3ebc9..49a613b9a47 100644 --- a/src/Simulation/Simulators/QuantumExecutor/M.cs +++ b/src/Simulation/Simulators/QuantumExecutor/M.cs @@ -1,7 +1,7 @@ -ο»Ώusing System; -using System.Diagnostics; -using System.Linq; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/Measure.cs b/src/Simulation/Simulators/QuantumExecutor/Measure.cs index 6c8c2dd90d7..98f6a89ce4f 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Measure.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Measure.cs @@ -1,6 +1,7 @@ -ο»Ώusing System; -using System.Collections.Generic; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs index bf1ad0cfe91..79270e6acf8 100644 --- a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs +++ b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +using System; using Microsoft.Quantum.Simulation.Common; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/R.cs b/src/Simulation/Simulators/QuantumExecutor/R.cs index e58e03f7eb1..93a91a07221 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R.cs +++ b/src/Simulation/Simulators/QuantumExecutor/R.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/R1.cs b/src/Simulation/Simulators/QuantumExecutor/R1.cs index b94bd038b40..1ae4d440caa 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R1.cs +++ b/src/Simulation/Simulators/QuantumExecutor/R1.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs b/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs index de2e6f4f22f..54b26df4b22 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs +++ b/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/RFrac.cs b/src/Simulation/Simulators/QuantumExecutor/RFrac.cs index 27d9955154f..cc7fef265d2 100644 --- a/src/Simulation/Simulators/QuantumExecutor/RFrac.cs +++ b/src/Simulation/Simulators/QuantumExecutor/RFrac.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/Release.cs b/src/Simulation/Simulators/QuantumExecutor/Release.cs index 4447c365f86..4aa94ffa091 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Release.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Release.cs @@ -1,4 +1,7 @@ -ο»Ώusing Microsoft.Quantum.Simulation.Core; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor { diff --git a/src/Simulation/Simulators/QuantumExecutor/Reset.cs b/src/Simulation/Simulators/QuantumExecutor/Reset.cs index 6c655d06e1b..3daec9ebb82 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Reset.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Reset.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/Return.cs b/src/Simulation/Simulators/QuantumExecutor/Return.cs index cdeeb859aa6..743ddfeb8d8 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Return.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Return.cs @@ -1,4 +1,7 @@ -ο»Ώnamespace Microsoft.Quantum.Simulation.QuantumExecutor +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.QuantumExecutor { using Microsoft.Quantum.Simulation.Core; diff --git a/src/Simulation/Simulators/QuantumExecutor/S.cs b/src/Simulation/Simulators/QuantumExecutor/S.cs index 510867fd758..1d8812df8d7 100644 --- a/src/Simulation/Simulators/QuantumExecutor/S.cs +++ b/src/Simulation/Simulators/QuantumExecutor/S.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/SWAP.cs b/src/Simulation/Simulators/QuantumExecutor/SWAP.cs index 8aeb05eefdc..7b96ecf6e73 100644 --- a/src/Simulation/Simulators/QuantumExecutor/SWAP.cs +++ b/src/Simulation/Simulators/QuantumExecutor/SWAP.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/T.cs b/src/Simulation/Simulators/QuantumExecutor/T.cs index 06e650b6056..55ecdfde021 100644 --- a/src/Simulation/Simulators/QuantumExecutor/T.cs +++ b/src/Simulation/Simulators/QuantumExecutor/T.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/X.cs b/src/Simulation/Simulators/QuantumExecutor/X.cs index 4bcb59e4f5b..a65e19d62b0 100644 --- a/src/Simulation/Simulators/QuantumExecutor/X.cs +++ b/src/Simulation/Simulators/QuantumExecutor/X.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/Y.cs b/src/Simulation/Simulators/QuantumExecutor/Y.cs index 89e37c6f1a1..bc64eb27500 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Y.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Y.cs @@ -1,5 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/Z.cs b/src/Simulation/Simulators/QuantumExecutor/Z.cs index 8a37d2999b3..2e7c3646e71 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Z.cs +++ b/src/Simulation/Simulators/QuantumExecutor/Z.cs @@ -1,6 +1,7 @@ -ο»Ώusing System; -using System.Runtime.InteropServices; -using Microsoft.Quantum.Intrinsic; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.Quantum.Simulation.Core; namespace Microsoft.Quantum.Simulation.QuantumExecutor diff --git a/src/Simulation/Simulators/QuantumExecutor/random.cs b/src/Simulation/Simulators/QuantumExecutor/random.cs index 4f10b3a1e68..38350175bad 100644 --- a/src/Simulation/Simulators/QuantumExecutor/random.cs +++ b/src/Simulation/Simulators/QuantumExecutor/random.cs @@ -1,4 +1,7 @@ -ο»Ώusing Microsoft.Quantum.Simulation.Core; +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; using System; namespace Microsoft.Quantum.Simulation.QuantumExecutor From d464610ef6f4c02804dc4643f48f1c3acfa2dbdb Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Fri, 1 Nov 2019 13:21:02 -0700 Subject: [PATCH 03/12] Cleanup --- src/Simulation/Common/IQuantumExecutor.cs | 3 +- .../QuantumExecutor/ClassicalControl.cs | 108 +++++++++--------- .../QuantumExecutor/EmptyQuantumExecutor.cs | 3 +- 3 files changed, 54 insertions(+), 60 deletions(-) diff --git a/src/Simulation/Common/IQuantumExecutor.cs b/src/Simulation/Common/IQuantumExecutor.cs index 09c0c018e02..3c9d1236250 100644 --- a/src/Simulation/Common/IQuantumExecutor.cs +++ b/src/Simulation/Common/IQuantumExecutor.cs @@ -7,8 +7,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor { /// - /// An interface for implementing QDK target machines which work - /// on a quantum circuit level. + /// An interface for implementing QDK target machines that work on a quantum circuit level. /// It is intended to be used with . /// /// diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs index fee486af63f..4320d0995b5 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs +++ b/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs @@ -17,8 +17,9 @@ public class SimApplyIfElse : Extensions.ApplyIfElseIntrinsic public override Func<(Result, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; }; } @@ -32,8 +33,9 @@ public class SimApplyIfElseA : Extensions.ApplyIfElseIntrinsicA public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; }; @@ -41,8 +43,8 @@ public class SimApplyIfElseA : Extensions.ApplyIfElseIntrinsicA { var (measurementResult, onZero, onOne) = q; Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, - () => onZero.Adjoint.Apply(QVoid.Instance), - () => onOne.Adjoint.Apply(QVoid.Instance)); + () => onZero.Adjoint.Apply(QVoid.Instance), + () => onOne.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; }; } @@ -56,19 +58,20 @@ public class SimApplyIfElseC : Extensions.ApplyIfElseIntrinsicC public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; }; - public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => - (q) => - { - var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled( - measurementResult, () => onZero.Controlled.Apply(ctrls), () => onOne.Controlled.Apply(ctrls)); - return QVoid.Instance; - }; + public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => (q) => + { + var (ctrls, (measurementResult, onZero, onOne)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Controlled.Apply(ctrls), + () => onOne.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; } public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA @@ -80,8 +83,9 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Apply(QVoid.Instance), + () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; }; @@ -89,40 +93,32 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA { var (measurementResult, onZero, onOne) = q; Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, - () => onZero.Adjoint.Apply(QVoid.Instance), - () => onOne.Adjoint.Apply(QVoid.Instance)); + () => onZero.Adjoint.Apply(QVoid.Instance), + () => onOne.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; }; public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, () => onZero.Controlled.Apply(ctrls), - () => onOne.Controlled.Apply(ctrls)); + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Controlled.Apply(ctrls), + () => onOne.Controlled.Apply(ctrls)); return QVoid.Instance; }; - public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => - (q) => - { - var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, - () => onZero.Controlled.Adjoint.Apply(ctrls), - () => onOne.Controlled.Adjoint.Apply(ctrls)); - return QVoid.Instance; - }; + public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => + { + var (ctrls, (measurementResult, onZero, onOne)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + () => onZero.Controlled.Adjoint.Apply(ctrls), + () => onOne.Controlled.Adjoint.Apply(ctrls)); + return QVoid.Instance; + }; } - - - - - - - - public class SimApplyConditionally : Extensions.ApplyConditionallyIntrinsic { private QuantumExecutorSimulator Simulator { get; } @@ -179,15 +175,14 @@ public class SimApplyConditionallyC : Extensions.ApplyConditionallyIntrinsicC return QVoid.Instance; }; - public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => //(q) => - (q) => - { - var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Controlled.Apply(ctrls), - () => onNonEqualOp.Controlled.Apply(ctrls)); - return QVoid.Instance; - }; + public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => (q) => + { + var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Controlled.Apply(ctrls), + () => onNonEqualOp.Controlled.Apply(ctrls)); + return QVoid.Instance; + }; } public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA @@ -223,15 +218,14 @@ public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA return QVoid.Instance; }; - public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => //(q) => - (q) => - { - var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Controlled.Adjoint.Apply(ctrls), - () => onNonEqualOp.Controlled.Adjoint.Apply(ctrls)); - return QVoid.Instance; - }; + public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => + { + var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; + Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + () => onEqualOp.Controlled.Adjoint.Apply(ctrls), + () => onNonEqualOp.Controlled.Adjoint.Apply(ctrls)); + return QVoid.Instance; + }; } } diff --git a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs index ae88f95835d..8b897d4d072 100644 --- a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs +++ b/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs @@ -7,7 +7,8 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor { /// - /// An example of IQuantumExecutor that throws for every call. + /// A class that implements IQuantumExecutor that does not do any logic, but is convenient to inherit from. + /// It throws for most APIs. /// class EmptyQuantumExecutor : IQuantumExecutor { From 634910b1c52cd3a306c5176b6eadd32040c757e4 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Wed, 13 Nov 2019 16:55:49 -0800 Subject: [PATCH 04/12] Fixed event regustration --- src/Simulation/Common/IQuantumExecutor.cs | 52 +++++++++---------- .../QuantumExecutorSimulator.cs | 1 + 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/Simulation/Common/IQuantumExecutor.cs b/src/Simulation/Common/IQuantumExecutor.cs index 3c9d1236250..70e63f38013 100644 --- a/src/Simulation/Common/IQuantumExecutor.cs +++ b/src/Simulation/Common/IQuantumExecutor.cs @@ -424,6 +424,31 @@ public interface IQuantumExecutor /// Qubit to which the gate should be applied. void Reset(Qubit qubit); + /// + /// Intended for a limited support of branching upon measurement results on a simulator level. + /// + /// The result of the measurement upon which branching is to be performed. + /// Corresponds to quantum program that must be executed if result is + /// Corresponds to quantum program that must be executed if result is + /// + /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . + /// The program is executed with the same instance of interface. + /// + void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); + + /// + /// Intended for a limited support of branching upon measurement results on a simulator level. + /// + /// The actual results of the measurements of a number of qubits upon which branching is to be performed. + /// The expected values of results of the measurements of these qubits. + /// Corresponds to quantum program that must be executed if all values are equal to corresponding + /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding + /// + /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . + /// The program is executed with the same instance of interface. + /// + void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); + /// /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. /// @@ -474,38 +499,13 @@ public interface IQuantumExecutor void OnOperationEnd(ICallable operation, IApplyData arguments); /// - /// Called in the end of the call to any Q# operation. + /// Called when an exception occurs. /// /// Information about exception that was raised. /// /// void OnFail(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo); - /// - /// Intended for a limited support of branching upon measurement results on a simulator level. - /// - /// The result of the measurement upon which branching is to be performed. - /// Corresponds to quantum program that must be executed if result is - /// Corresponds to quantum program that must be executed if result is - /// - /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. - /// - void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); - - /// - /// Intended for a limited support of branching upon measurement results on a simulator level. - /// - /// The actual results of the measurements of a number of qubits upon which branching is to be performed. - /// The expected values of results of the measurements of these qubits. - /// Corresponds to quantum program that must be executed if all values are equal to corresponding - /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding - /// - /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. - /// - void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); - /// /// Called when qubits are allocated by Q# using block. /// diff --git a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs index 79270e6acf8..9e4024c9790 100644 --- a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs +++ b/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs @@ -41,6 +41,7 @@ public QuantumExecutorSimulator(IQuantumExecutor quantumExecutor = null, IQubitM QuantumExecutor = quantumExecutor ?? new EmptyQuantumExecutor(); OnOperationStart += QuantumExecutor.OnOperationStart; OnOperationEnd += QuantumExecutor.OnOperationEnd; + OnFail += QuantumExecutor.OnFail; OnLog += QuantumExecutor.OnMessage; } From 9d2c99b234007c3f77fc8f366ebd17bad9b1742c Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Fri, 22 Nov 2019 19:46:19 -0800 Subject: [PATCH 05/12] Addressed code reviews. --- .../EmptyQuantumProcessor.cs} | 14 +-- ...uantumExecutor.cs => IQuantumProcessor.cs} | 84 +++++++++--------- src/Simulation/Common/Utils.cs | 10 +-- .../Simulators/QuantumExecutor/Allocate.cs | 32 ------- .../Simulators/QuantumExecutor/Borrow.cs | 32 ------- .../Simulators/QuantumExecutor/Dump.cs | 68 -------------- .../Simulators/QuantumExecutor/M.cs | 26 ------ .../Simulators/QuantumExecutor/Reset.cs | 29 ------ .../Simulators/QuantumProcessor/Allocate.cs | 32 +++++++ .../Assert.cs | 12 +-- .../AssertProb.cs | 14 ++- .../Simulators/QuantumProcessor/Borrow.cs | 32 +++++++ .../ClassicalControl.cs | 88 +++++++++---------- .../ClassicalControl.qs | 10 ++- .../Simulators/QuantumProcessor/Dump.cs | 49 +++++++++++ .../Exp.cs | 16 ++-- .../ExpFrac.cs | 16 ++-- .../H.cs | 17 ++-- .../Simulators/QuantumProcessor/M.cs | 26 ++++++ .../Measure.cs | 13 ++- .../QuantumProcessorDispatcher.cs} | 28 +++--- .../R.cs | 17 ++-- .../R1.cs | 18 ++-- .../R1Frac.cs | 18 ++-- .../RFrac.cs | 17 ++-- .../Release.cs | 14 +-- .../Simulators/QuantumProcessor/Reset.cs | 27 ++++++ .../Return.cs | 14 +-- .../S.cs | 22 ++--- .../SWAP.cs | 17 ++-- .../T.cs | 23 ++--- .../X.cs | 17 ++-- .../Y.cs | 17 ++-- .../Z.cs | 16 ++-- .../random.cs | 10 +-- 35 files changed, 420 insertions(+), 475 deletions(-) rename src/Simulation/{Simulators/QuantumExecutor/EmptyQuantumExecutor.cs => Common/EmptyQuantumProcessor.cs} (93%) rename src/Simulation/Common/{IQuantumExecutor.cs => IQuantumProcessor.cs} (91%) delete mode 100644 src/Simulation/Simulators/QuantumExecutor/Allocate.cs delete mode 100644 src/Simulation/Simulators/QuantumExecutor/Borrow.cs delete mode 100644 src/Simulation/Simulators/QuantumExecutor/Dump.cs delete mode 100644 src/Simulation/Simulators/QuantumExecutor/M.cs delete mode 100644 src/Simulation/Simulators/QuantumExecutor/Reset.cs create mode 100644 src/Simulation/Simulators/QuantumProcessor/Allocate.cs rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Assert.cs (77%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/AssertProb.cs (78%) create mode 100644 src/Simulation/Simulators/QuantumProcessor/Borrow.cs rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/ClassicalControl.cs (68%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/ClassicalControl.qs (95%) create mode 100644 src/Simulation/Simulators/QuantumProcessor/Dump.cs rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Exp.cs (78%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/ExpFrac.cs (79%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/H.cs (56%) create mode 100644 src/Simulation/Simulators/QuantumProcessor/M.cs rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Measure.cs (65%) rename src/Simulation/Simulators/{QuantumExecutor/QuantumExecutorSimulator.cs => QuantumProcessor/QuantumProcessorDispatcher.cs} (54%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/R.cs (72%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/R1.cs (70%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/R1Frac.cs (72%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/RFrac.cs (74%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Release.cs (50%) create mode 100644 src/Simulation/Simulators/QuantumProcessor/Reset.cs rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Return.cs (50%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/S.cs (62%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/SWAP.cs (55%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/T.cs (62%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/X.cs (56%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Y.cs (58%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/Z.cs (57%) rename src/Simulation/Simulators/{QuantumExecutor => QuantumProcessor}/random.cs (81%) diff --git a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs b/src/Simulation/Common/EmptyQuantumProcessor.cs similarity index 93% rename from src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs rename to src/Simulation/Common/EmptyQuantumProcessor.cs index 8b897d4d072..8fc430ec515 100644 --- a/src/Simulation/Simulators/QuantumExecutor/EmptyQuantumExecutor.cs +++ b/src/Simulation/Common/EmptyQuantumProcessor.cs @@ -4,13 +4,13 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.Common { /// - /// A class that implements IQuantumExecutor that does not do any logic, but is convenient to inherit from. + /// A class that implements IQuantumProcessor that does not do any logic, but is convenient to inherit from. /// It throws for most APIs. /// - class EmptyQuantumExecutor : IQuantumExecutor + class EmptyQuantumProcessor : IQuantumProcessor { public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) { @@ -70,7 +70,7 @@ public virtual void ControlledS(IQArray controls, Qubit qubit) throw new NotImplementedException(); } - public virtual void ControlledSAdj(IQArray controls, Qubit qubit) + public virtual void ControlledSAdjoint(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } @@ -85,7 +85,7 @@ public virtual void ControlledT(IQArray controls, Qubit qubit) throw new NotImplementedException(); } - public virtual void ControlledTAdj(IQArray controls, Qubit qubit) + public virtual void ControlledTAdjoint(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } @@ -200,7 +200,7 @@ public virtual void S(Qubit qubit) throw new NotImplementedException(); } - public virtual void SAdj(Qubit qubit) + public virtual void SAdjoint(Qubit qubit) { throw new NotImplementedException(); } @@ -215,7 +215,7 @@ public virtual void T(Qubit qubit) throw new NotImplementedException(); } - public virtual void TAdj(Qubit qubit) + public virtual void TAdjoint(Qubit qubit) { throw new NotImplementedException(); } diff --git a/src/Simulation/Common/IQuantumExecutor.cs b/src/Simulation/Common/IQuantumProcessor.cs similarity index 91% rename from src/Simulation/Common/IQuantumExecutor.cs rename to src/Simulation/Common/IQuantumProcessor.cs index 70e63f38013..32781accc87 100644 --- a/src/Simulation/Common/IQuantumExecutor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -4,24 +4,26 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.Common { /// - /// An interface for implementing QDK target machines that work on a quantum circuit level. - /// It is intended to be used with . + /// An interface for implementing QDK target quantum machines that work on a quantum circuit level. /// /// - /// Simulators implemented using interface do not manage qubits on their own. - /// Instead they are notified when qubits are allocated, released, borrowed and returned. + /// To implement a target machine that executes quantum commands, implement this interface. + /// Consider using as a stub for easy impementation of this interface. + /// Implementors of interface do not manage qubits on their own. + /// All qubit management (allocation, dealocation, etc.) is done by the caller of this interface. + /// Implementors are notified when qubits are allocated, released, borrowed and returned allowing them to react to these events if necessary. /// - public interface IQuantumExecutor + public interface IQuantumProcessor { /// /// Called when Microsoft.Quantum.Intrinsic.X is called in Q#. /// In Q# the operation applies X gate to . The gate is given by matrix X=((0,1),(1,0)). /// /// - /// When adjoint of X is called in Q#, is called because X is self-adjoint. + /// When adjoint of X is called in Q#, this same method is called because X is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -32,7 +34,7 @@ public interface IQuantumExecutor /// In Q# the operation applies X gate to controlled on . The gate is given by matrix X=((0,1),(1,0)). /// /// - /// When adjoint of Controlled X is called in Q#, is called because X is self-adjoint. + /// When adjoint of Controlled X is called in Q#, this same method is called because X is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -44,7 +46,7 @@ public interface IQuantumExecutor /// In Q# the operation applies Y gate to . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// - /// When adjoint of Y is called in Q#, is called because Y is self-adjoint. + /// When adjoint of Y is called in Q#, this same method is called because Y is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -55,7 +57,7 @@ public interface IQuantumExecutor /// In Q# the operation applies X gate to controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// - /// When adjoint of Controlled Y is called in Q#, is called because Y is self-adjoint. + /// When adjoint of Controlled Y is called in Q#, this same method is called because Y is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -67,7 +69,7 @@ public interface IQuantumExecutor /// In Q# the operation applies Z gate to . The gate is given by matrix Z=((1,0),(0,-1)). /// /// - /// When adjoint of Z is called in Q#, is called because Z is self-adjoint. + /// When adjoint of Z is called in Q#, this same method is called because Z is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -78,7 +80,7 @@ public interface IQuantumExecutor /// In Q# the operation applies Z gate to controlled on . The gate is given by matrix Z=((1,0),(0,-1)). /// /// - /// When adjoint of Controlled Z is called in Q#, is called because Z is self-adjoint. + /// When adjoint of Controlled Z is called in Q#, this same method is called because Z is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -90,7 +92,7 @@ public interface IQuantumExecutor /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states. /// /// - /// When adjoint of SWAP is called in Q#, is called because SWAP is self-adjoint. + /// When adjoint of SWAP is called in Q#, this same method is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// First qubit to be swapped. @@ -102,7 +104,7 @@ public interface IQuantumExecutor /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states controlled on . /// /// - /// When adjoint of Controlled SWAP is called in Q#, is called because SWAP is self-adjoint. + /// When adjoint of Controlled SWAP is called in Q#, this same method is called because SWAP is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -115,7 +117,7 @@ public interface IQuantumExecutor /// In Q# the operation applies Hadamard gate to . The gate is given by matrix H=((1,1),(1,-1))/√2. /// /// - /// When adjoint of H is called in Q#, is called because Hadamard is self-adjoint. + /// When adjoint of H is called in Q#, this same method is called because Hadamard is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -126,7 +128,7 @@ public interface IQuantumExecutor /// In Q# the operation applies Hadamard gate to controlled on . The gate is given by matrix H=((1,1),(1,-1))/√2. /// /// - /// When adjoint of Controlled H is called in Q#, is called because Hadamard is self-adjoint. + /// When adjoint of Controlled H is called in Q#, this same method is called because Hadamard is self-adjoint. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -138,7 +140,7 @@ public interface IQuantumExecutor /// In Q# the operation applies S gate to . The gate is given by matrix S=((1,0),(0,𝑖)). /// /// - /// When adjoint of S is called in Q#, is called. + /// When adjoint of S is called in Q#, is called. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -149,7 +151,7 @@ public interface IQuantumExecutor /// In Q# the operation applies S gate to controlled on . The gate is given by matrix S=((1,0),(0,𝑖)). /// /// - /// When adjoint of Controlled S is called in Q#, is called. + /// When adjoint of Controlled S is called in Q#, is called. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -165,7 +167,7 @@ public interface IQuantumExecutor /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. - void SAdj(Qubit qubit); + void SAdjoint(Qubit qubit); /// /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.S is called in Q#. @@ -177,14 +179,14 @@ public interface IQuantumExecutor /// /// The array of qubits on which the operation is controlled. /// Qubit to which the gate should be applied. - void ControlledSAdj(IQArray controls, Qubit qubit); + void ControlledSAdjoint(IQArray controls, Qubit qubit); /// /// Called when Microsoft.Quantum.Intrinsic.T is called in Q#. /// In Q# the operation applies T gate to . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). /// /// - /// When adjoint of T is called in Q#, is called. + /// When adjoint of T is called in Q#, is called. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. @@ -195,7 +197,7 @@ public interface IQuantumExecutor /// In Q# the operation applies T gate to controlled on . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). /// /// - /// When adjoint of Controlled T is called in Q#, is called. + /// When adjoint of Controlled T is called in Q#, is called. /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// The array of qubits on which the operation is controlled. @@ -211,7 +213,7 @@ public interface IQuantumExecutor /// The names and the order of the parameters are the same as for the corresponding Q# operation. /// /// Qubit to which the gate should be applied. - void TAdj(Qubit qubit); + void TAdjoint(Qubit qubit); /// /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.T is called in Q#. @@ -223,7 +225,7 @@ public interface IQuantumExecutor /// /// The array of qubits on which the operation is controlled. /// Qubit to which the gate should be applied. - void ControlledTAdj(IQArray controls, Qubit qubit); + void ControlledTAdjoint(IQArray controls, Qubit qubit); /// /// Called when Microsoft.Quantum.Intrinsic.R is called in Q#. @@ -395,7 +397,7 @@ public interface IQuantumExecutor /// /// /// The names and the order of the parameters are the same as for the corresponding Q# operation. - /// Class implementing interface can return any class derived from . + /// Class implementing interface can return any class derived from . /// /// Qubit to which the gate should be applied. /// Zero if the +1 eigenvalue is observed, and One if the -1 eigenvalue is observed. @@ -407,7 +409,7 @@ public interface IQuantumExecutor /// /// /// The names and the order of the parameters are the same as for the corresponding Q# operation. - /// Class implementing interface can return any class derived from . + /// Class implementing interface can return any class derived from . /// /// Qubits to which the gate should be applied. /// Array of single-qubit Pauli values describing multi-qubit Pauli observable. @@ -425,19 +427,19 @@ public interface IQuantumExecutor void Reset(Qubit qubit); /// - /// Intended for a limited support of branching upon measurement results on a simulator level. + /// Intended for a limited support of branching upon measurement results on a target machine level. /// /// The result of the measurement upon which branching is to be performed. /// Corresponds to quantum program that must be executed if result is /// Corresponds to quantum program that must be executed if result is /// /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. + /// The program is executed with the same instance of interface. /// void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); /// - /// Intended for a limited support of branching upon measurement results on a simulator level. + /// Intended for a limited support of branching upon measurement results on a target machine level. /// /// The actual results of the measurements of a number of qubits upon which branching is to be performed. /// The expected values of results of the measurements of these qubits. @@ -445,7 +447,7 @@ public interface IQuantumExecutor /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding /// /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. + /// The program is executed with the same instance of interface. /// void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); @@ -462,7 +464,7 @@ public interface IQuantumExecutor void Assert(IQArray bases, IQArray qubits, Result result, string msg); /// - /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. /// /// /// The names and the order of the parameters is similar to the corresponding Q# operation./ @@ -480,6 +482,7 @@ public interface IQuantumExecutor /// Information about operation being called. /// Information about the arguments passed to the operation. /// + /// Implement this interface if you want to be notified every time a Q# operation starts. /// To get the fully qualified Q# name of operation being called use . /// For the variant of operation, that is to find if Adjoint, Controlled or Controlled Adjoint being called use . /// To get a sequence of all qubits passed to the operation use . @@ -492,6 +495,7 @@ public interface IQuantumExecutor /// Information about operation being called. /// Information about the arguments passed to the operation. /// + /// Implement this interface if you want to be notified every time a Q# operation ends. /// To get the fully qualified Q# name of operation being called use . /// For the variant of operation, that is to find if Adjoint, Controlled or Controlled Adjoint being called use . /// To get a sequence of all qubits passed to the operation use . @@ -499,7 +503,7 @@ public interface IQuantumExecutor void OnOperationEnd(ICallable operation, IApplyData arguments); /// - /// Called when an exception occurs. + /// Called when an exception occurs. This could be Fail statement in Q#, or any other exception. /// /// Information about exception that was raised. /// @@ -509,9 +513,9 @@ public interface IQuantumExecutor /// /// Called when qubits are allocated by Q# using block. /// - /// Qubits that are allocated. + /// Qubits that are being allocated. /// - /// Every qubit in simulation framework has a unique identifier . + /// Every qubit has a unique identifier . /// All newly allocated qubits are in |0⟩ state. /// void OnAllocateQubits(IQArray qubits); @@ -519,9 +523,9 @@ public interface IQuantumExecutor /// /// Called when qubits are released in Q# in the end of using block. /// - /// Qubits that are released. + /// Qubits that are being released. /// - /// Every qubit in simulation framework has a unique identifier . + /// Every qubit has a unique identifier . /// All qubits are expected to be released in |0⟩ state. /// void OnReleaseQubits(IQArray qubits); @@ -529,9 +533,9 @@ public interface IQuantumExecutor /// /// Called when qubits are borrowed by Q# borrowing block. /// - /// Qubits that are borrowed. + /// Qubits that are being borrowed. /// - /// Every qubit in simulation framework has a unique identifier . + /// Every qubit has a unique identifier . /// Borrowed qubits can be in any state. /// void OnBorrowQubits(IQArray qubits); @@ -539,9 +543,9 @@ public interface IQuantumExecutor /// /// Called when qubits are returned in the end of Q# borrowing block. /// - /// Qubits that has been allocated. + /// Qubits that have been borrowed and are now being returned. /// - /// Every qubit in simulation framework has a unique identifier . + /// Every qubit has a unique identifier . /// Borrowed qubits are expected to be returned in the same state as the state they have been borrowed in. /// void OnReturnQubits(IQArray qubits); diff --git a/src/Simulation/Common/Utils.cs b/src/Simulation/Common/Utils.cs index 04df6315d59..752c4048dcd 100644 --- a/src/Simulation/Common/Utils.cs +++ b/src/Simulation/Common/Utils.cs @@ -13,19 +13,19 @@ public class CommonUtils /// Removes PauliI terms from observable and corresponding qubits from qubits. /// Returns the observable description that is equivalent to the original one, but has no PauliI terms /// - public static void PruneObservable(IQArray observable, IQArray qubits, out QArray prunnedObservable, out QArray prunnedQubits) + public static void PruneObservable(IQArray observable, IQArray qubits, out QArray prunedObservable, out QArray prunedQubits) { Debug.Assert(observable != null); Debug.Assert(qubits != null); Debug.Assert(observable.Length == qubits.Length); - prunnedObservable = new QArray(PrunnedSequence(observable, Pauli.PauliI, observable)); - prunnedQubits = new QArray(PrunnedSequence(observable, Pauli.PauliI, qubits)); + prunedObservable = new QArray(PrunedSequence(observable, Pauli.PauliI, observable)); + prunedQubits = new QArray(PrunedSequence(observable, Pauli.PauliI, qubits)); } /// - /// Returns IEnumerable that contains sub-sequence of [i], such that [i] is not equal to . + /// Returns IEnumerable<T> that contains sub-sequence of [i], such that [i] is not equal to . /// - public static IEnumerable PrunnedSequence(IQArray sequence, U value, IQArray sequenceToPrune ) + public static IEnumerable PrunedSequence(IQArray sequence, U value, IQArray sequenceToPrune ) { for (uint i = 0; i < sequence.Length; ++i) { diff --git a/src/Simulation/Simulators/QuantumExecutor/Allocate.cs b/src/Simulation/Simulators/QuantumExecutor/Allocate.cs deleted file mode 100644 index 04ceba85113..00000000000 --- a/src/Simulation/Simulators/QuantumExecutor/Allocate.cs +++ /dev/null @@ -1,32 +0,0 @@ -ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.QuantumExecutor -{ - public partial class QuantumExecutorSimulator - { - public class QuantumExecutorSimAllocate : Intrinsic.Allocate - { - private readonly QuantumExecutorSimulator sim; - public QuantumExecutorSimAllocate(QuantumExecutorSimulator m) : base(m){ - sim = m; - } - - public override Qubit Apply() - { - IQArray qubits = sim.QubitManager.Allocate(1); - sim.QuantumExecutor.OnAllocateQubits(qubits); - return qubits[0]; - } - - public override IQArray Apply( long count ) - { - IQArray qubits = sim.QubitManager.Allocate(count); - sim.QuantumExecutor.OnAllocateQubits(qubits); - return qubits; - } - } - } -} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/Borrow.cs b/src/Simulation/Simulators/QuantumExecutor/Borrow.cs deleted file mode 100644 index 0dbfe80e838..00000000000 --- a/src/Simulation/Simulators/QuantumExecutor/Borrow.cs +++ /dev/null @@ -1,32 +0,0 @@ -ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.QuantumExecutor -{ - public partial class QuantumExecutorSimulator - { - public class QuantumExecutorSimBorrow : Intrinsic.Borrow - { - private readonly QuantumExecutorSimulator sim; - public QuantumExecutorSimBorrow(QuantumExecutorSimulator m) : base(m){ - sim = m; - } - - public override Qubit Apply() - { - IQArray qubits = sim.QubitManager.Borrow(1); - sim.QuantumExecutor.OnBorrowQubits(qubits); - return qubits[0]; - } - - public override IQArray Apply( long count ) - { - IQArray qubits = sim.QubitManager.Borrow(1); - sim.QuantumExecutor.OnBorrowQubits(qubits); - return qubits; - } - } - } -} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/Dump.cs b/src/Simulation/Simulators/QuantumExecutor/Dump.cs deleted file mode 100644 index 749631d9f90..00000000000 --- a/src/Simulation/Simulators/QuantumExecutor/Dump.cs +++ /dev/null @@ -1,68 +0,0 @@ -ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.QuantumExecutor -{ - public partial class QuantumExecutorSimulator - { - /// - /// Dumps the wave function for the given qubits into the given target. - /// If the target is QVoid or an empty string, it dumps it to the console - /// using the `Message` function, otherwise it dumps the content into a file - /// with the given name. - /// DumpMachine dumps the entire wave function, - /// DumpRegister attempts to create the wave function or the resulting subsystem; if it fails - /// because the qubits are entangled with some external qubit, it just generates a message. - /// - protected virtual QVoid DumpMachine(T target) - { - QuantumExecutor.OnDumpMachine(target); - return QVoid.Instance; - } - - protected virtual QVoid DumpRegister(T target, IQArray qubits) - { - QuantumExecutor.OnDumpRegister(target, qubits); - return QVoid.Instance; - } - - public class QuantumExecutorSimDumpMachine : Quantum.Diagnostics.DumpMachine - { - private QuantumExecutorSimulator Simulator { get; } - - public QuantumExecutorSimDumpMachine(QuantumExecutorSimulator m) : base(m) - { - this.Simulator = m; - } - - public override Func Body => (location) => - { - if (location == null) { throw new ArgumentNullException(nameof(location)); } - - return Simulator.DumpMachine(location); - }; - } - - public class QuantumExecutorSimDumpRegister : Quantum.Diagnostics.DumpRegister - { - private QuantumExecutorSimulator Simulator { get; } - - - public QuantumExecutorSimDumpRegister(QuantumExecutorSimulator m) : base(m) - { - this.Simulator = m; - } - - public override Func<(T, IQArray), QVoid> Body => (__in) => - { - var (location, qubits) = __in; - - if (location == null) { throw new ArgumentNullException(nameof(location)); } - return Simulator.DumpRegister(location, qubits); - }; - } - } -} diff --git a/src/Simulation/Simulators/QuantumExecutor/M.cs b/src/Simulation/Simulators/QuantumExecutor/M.cs deleted file mode 100644 index 49a613b9a47..00000000000 --- a/src/Simulation/Simulators/QuantumExecutor/M.cs +++ /dev/null @@ -1,26 +0,0 @@ -ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.QuantumExecutor -{ - public partial class QuantumExecutorSimulator - { - public class QuantumExecutorSimM : Quantum.Intrinsic.M - { - private QuantumExecutorSimulator Simulator { get; } - - public QuantumExecutorSimM(QuantumExecutorSimulator m) : base(m) - { - this.Simulator = m; - } - - public override Func Body => (q) => - { - return Simulator.QuantumExecutor.M(q); - }; - } - } -} diff --git a/src/Simulation/Simulators/QuantumExecutor/Reset.cs b/src/Simulation/Simulators/QuantumExecutor/Reset.cs deleted file mode 100644 index 3daec9ebb82..00000000000 --- a/src/Simulation/Simulators/QuantumExecutor/Reset.cs +++ /dev/null @@ -1,29 +0,0 @@ -ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.QuantumExecutor -{ - public partial class QuantumExecutorSimulator - { - public class QuantumExecutorSimReset : Quantum.Intrinsic.Reset - { - private QuantumExecutorSimulator Simulator { get; } - - - public QuantumExecutorSimReset(QuantumExecutorSimulator m) : base(m) - { - this.Simulator = m; - } - - public override Func Body => (q1) => - { - - Simulator.QuantumExecutor.Reset(q1); - return QVoid.Instance; - }; - } - } -} diff --git a/src/Simulation/Simulators/QuantumProcessor/Allocate.cs b/src/Simulation/Simulators/QuantumProcessor/Allocate.cs new file mode 100644 index 00000000000..ea176410f61 --- /dev/null +++ b/src/Simulation/Simulators/QuantumProcessor/Allocate.cs @@ -0,0 +1,32 @@ +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumProcessor +{ + public partial class QuantumProcessorDispatcher + { + public class QuantumProcessorDispatcherAllocate : Intrinsic.Allocate + { + private readonly QuantumProcessorDispatcher sim; + public QuantumProcessorDispatcherAllocate(QuantumProcessorDispatcher m) : base(m){ + sim = m; + } + + public override Qubit Apply() + { + IQArray qubits = sim.QubitManager.Allocate(1); + sim.QuantumProcessor.OnAllocateQubits(qubits); + return qubits[0]; + } + + public override IQArray Apply(long count) + { + IQArray qubits = sim.QubitManager.Allocate(count); + sim.QuantumProcessor.OnAllocateQubits(qubits); + return qubits; + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/Assert.cs b/src/Simulation/Simulators/QuantumProcessor/Assert.cs similarity index 77% rename from src/Simulation/Simulators/QuantumExecutor/Assert.cs rename to src/Simulation/Simulators/QuantumProcessor/Assert.cs index 64450284bb3..d60f8bcef4e 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Assert.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Assert.cs @@ -5,15 +5,15 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimAssert : Quantum.Intrinsic.Assert + public class QuantumProcessorDispatcherAssert : Quantum.Intrinsic.Assert { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public QuantumExecutorSimAssert(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherAssert(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } @@ -28,7 +28,7 @@ public QuantumExecutorSimAssert(QuantumExecutorSimulator m) : base(m) } CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.Assert(newPaulis, newQubits, result, msg); + Simulator.QuantumProcessor.Assert(newPaulis, newQubits, result, msg); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs b/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs similarity index 78% rename from src/Simulation/Simulators/QuantumExecutor/AssertProb.cs rename to src/Simulation/Simulators/QuantumProcessor/AssertProb.cs index 1b283a44804..8d7d31eb8b3 100644 --- a/src/Simulation/Simulators/QuantumExecutor/AssertProb.cs +++ b/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs @@ -5,17 +5,15 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimAssertProb : Quantum.Intrinsic.AssertProb + public class QuantumProcessorDispatcherAssertProb : Quantum.Intrinsic.AssertProb { + private QuantumProcessorDispatcher Simulator { get; } - private QuantumExecutorSimulator Simulator { get; } - - - public QuantumExecutorSimAssertProb(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherAssertProb(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } @@ -31,7 +29,7 @@ public QuantumExecutorSimAssertProb(QuantumExecutorSimulator m) : base(m) double probabilityOfZero = result == Result.Zero ? expectedPr : 1.0 - expectedPr; CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.AssertProb(newPaulis, newQubits, probabilityOfZero, msg, tol ); + Simulator.QuantumProcessor.AssertProb(newPaulis, newQubits, probabilityOfZero, msg, tol ); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumProcessor/Borrow.cs b/src/Simulation/Simulators/QuantumProcessor/Borrow.cs new file mode 100644 index 00000000000..bc68f6be23d --- /dev/null +++ b/src/Simulation/Simulators/QuantumProcessor/Borrow.cs @@ -0,0 +1,32 @@ +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumProcessor +{ + public partial class QuantumProcessorDispatcher + { + public class QuantumProcessorDispatcherBorrow : Intrinsic.Borrow + { + private readonly QuantumProcessorDispatcher sim; + public QuantumProcessorDispatcherBorrow(QuantumProcessorDispatcher m) : base(m){ + sim = m; + } + + public override Qubit Apply() + { + IQArray qubits = sim.QubitManager.Borrow(1); + sim.QuantumProcessor.OnBorrowQubits(qubits); + return qubits[0]; + } + + public override IQArray Apply(long count) + { + IQArray qubits = sim.QubitManager.Borrow(count); + sim.QuantumProcessor.OnBorrowQubits(qubits); + return qubits; + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs similarity index 68% rename from src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs rename to src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs index 4320d0995b5..aa799e79c91 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.cs +++ b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs @@ -4,36 +4,36 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class SimApplyIfElse : Extensions.ApplyIfElseIntrinsic + public class QuantumProcessorApplyIfElse : Extensions.ApplyIfElseIntrinsic { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyIfElse(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyIfElse(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Result, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; }; } - public class SimApplyIfElseA : Extensions.ApplyIfElseIntrinsicA + public class QuantumProcessorApplyIfElseA : Extensions.ApplyIfElseIntrinsicA { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyIfElseA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyIfElseA(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; @@ -42,23 +42,23 @@ public class SimApplyIfElseA : Extensions.ApplyIfElseIntrinsicA public override Func<(Result, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Adjoint.Apply(QVoid.Instance), () => onOne.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; }; } - public class SimApplyIfElseC : Extensions.ApplyIfElseIntrinsicC + public class QuantumProcessorApplyIfElseC : Extensions.ApplyIfElseIntrinsicC { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyIfElseC(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyIfElseC(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; @@ -67,23 +67,23 @@ public class SimApplyIfElseC : Extensions.ApplyIfElseIntrinsicC public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Controlled.Apply(ctrls), () => onOne.Controlled.Apply(ctrls)); return QVoid.Instance; }; } - public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA + public class QuantumProcessorApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyIfElseCA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyIfElseCA(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Apply(QVoid.Instance), () => onOne.Apply(QVoid.Instance)); return QVoid.Instance; @@ -92,7 +92,7 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(Result, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Adjoint.Apply(QVoid.Instance), () => onOne.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; @@ -101,7 +101,7 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Controlled.Apply(ctrls), () => onOne.Controlled.Apply(ctrls)); return QVoid.Instance; @@ -110,7 +110,7 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResult, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, () => onZero.Controlled.Adjoint.Apply(ctrls), () => onOne.Controlled.Adjoint.Apply(ctrls)); return QVoid.Instance; @@ -119,32 +119,32 @@ public class SimApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA - public class SimApplyConditionally : Extensions.ApplyConditionallyIntrinsic + public class QuantumProcessorApplyConditionally : Extensions.ApplyConditionallyIntrinsic { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyConditionally(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyConditionally(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, IQArray, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Apply(QVoid.Instance), () => onNonEqualOp.Apply(QVoid.Instance)); return QVoid.Instance; }; } - public class SimApplyConditionallyA : Extensions.ApplyConditionallyIntrinsicA + public class QuantumProcessorApplyConditionallyA : Extensions.ApplyConditionallyIntrinsicA { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyConditionallyA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyConditionallyA(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Apply(QVoid.Instance), () => onNonEqualOp.Apply(QVoid.Instance)); return QVoid.Instance; @@ -153,23 +153,23 @@ public class SimApplyConditionallyA : Extensions.ApplyConditionallyIntrinsicA public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Adjoint.Apply(QVoid.Instance), () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; }; } - public class SimApplyConditionallyC : Extensions.ApplyConditionallyIntrinsicC + public class QuantumProcessorApplyConditionallyC : Extensions.ApplyConditionallyIntrinsicC { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyConditionallyC(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyConditionallyC(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Apply(QVoid.Instance), () => onNonEqualOp.Apply(QVoid.Instance)); return QVoid.Instance; @@ -178,23 +178,23 @@ public class SimApplyConditionallyC : Extensions.ApplyConditionallyIntrinsicC public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Controlled.Apply(ctrls), () => onNonEqualOp.Controlled.Apply(ctrls)); return QVoid.Instance; }; } - public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA + public class QuantumProcessorApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public SimApplyConditionallyCA(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorApplyConditionallyCA(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Apply(QVoid.Instance), () => onNonEqualOp.Apply(QVoid.Instance)); return QVoid.Instance; @@ -203,7 +203,7 @@ public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Adjoint.Apply(QVoid.Instance), () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); return QVoid.Instance; @@ -212,7 +212,7 @@ public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Controlled.Apply(ctrls), () => onNonEqualOp.Controlled.Apply(ctrls)); return QVoid.Instance; @@ -221,7 +221,7 @@ public class SimApplyConditionallyCA : Extensions.ApplyConditionallyIntrinsicCA public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumExecutor.ClassicallyControlled(measurementResults, resultsValues, + Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, () => onEqualOp.Controlled.Adjoint.Apply(ctrls), () => onNonEqualOp.Controlled.Adjoint.Apply(ctrls)); return QVoid.Instance; diff --git a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs similarity index 95% rename from src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs rename to src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs index f98b6e23c3a..20810640212 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ClassicalControl.qs +++ b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs @@ -1,13 +1,13 @@ ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions +namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions { open Microsoft.Quantum.Intrinsic; operation NoOp() : Unit is Ctl + Adj {} - + // Private helper operations. operation Delay<'T>(op : ('T => Unit), arg : 'T, aux : Unit) : Unit { op(arg); } @@ -25,6 +25,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Private helper operations. operation ApplyIfElseIntrinsic(measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit)) : Unit { body intrinsic; } @@ -47,6 +48,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Private helper operations. operation ApplyConditionallyIntrinsic(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit) , onNonEqualOp : (Unit => Unit)) : Unit { body intrinsic; } @@ -69,6 +71,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Public operations that match Canon names. operation ApplyIfElseR<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) , (onResultOneOp : ('U => Unit), oneArg : 'U)) : Unit { let zeroOp = Delay(onResultZeroOp, zeroArg, _); let oneOp = Delay(onResultOneOp, oneArg, _); @@ -94,6 +97,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Public operations that match Canon names. operation ApplyIfZero<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T)) : Unit { let zeroOp = Delay(onResultZeroOp, zeroArg, _); let oneOp = Delay(NoOp, (), _); @@ -119,6 +123,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Public operations that match Canon names. operation ApplyIfOne<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit), oneArg : 'T)) : Unit { let oneOp = Delay(onResultOneOp, oneArg, _); let zeroOp = Delay(NoOp, (), _); @@ -144,6 +149,7 @@ namespace Microsoft.Quantum.Simulation.QuantumExecutor.Extensions } + // Public operations that match Canon names. operation ApplyConditionally<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit), equalArg : 'T) , (onNonEqualOp : ('U => Unit), nonEqualArg : 'U)) : Unit { let equalOp = Delay(onEqualOp,equalArg,_); let nonEqualOp = Delay(onNonEqualOp,nonEqualArg,_); diff --git a/src/Simulation/Simulators/QuantumProcessor/Dump.cs b/src/Simulation/Simulators/QuantumProcessor/Dump.cs new file mode 100644 index 00000000000..a0b2ce227f7 --- /dev/null +++ b/src/Simulation/Simulators/QuantumProcessor/Dump.cs @@ -0,0 +1,49 @@ +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumProcessor +{ + public partial class QuantumProcessorDispatcher + { + public class QuantumProcessorDispatcherDumpMachine : Quantum.Diagnostics.DumpMachine + { + private QuantumProcessorDispatcher Simulator { get; } + + public QuantumProcessorDispatcherDumpMachine(QuantumProcessorDispatcher m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (location) => + { + if (location == null) { throw new ArgumentNullException(nameof(location)); } + + this.Simulator.QuantumProcessor.OnDumpMachine(location); + return QVoid.Instance; + }; + } + + public class QuantumProcessorDispatcherDumpRegister : Quantum.Diagnostics.DumpRegister + { + private QuantumProcessorDispatcher Simulator { get; } + + + public QuantumProcessorDispatcherDumpRegister(QuantumProcessorDispatcher m) : base(m) + { + this.Simulator = m; + } + + public override Func<(T, IQArray), QVoid> Body => (__in) => + { + var (location, qubits) = __in; + + if (location == null) { throw new ArgumentNullException(nameof(location)); } + this.Simulator.QuantumProcessor.OnDumpRegister(location, qubits); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Exp.cs b/src/Simulation/Simulators/QuantumProcessor/Exp.cs similarity index 78% rename from src/Simulation/Simulators/QuantumExecutor/Exp.cs rename to src/Simulation/Simulators/QuantumProcessor/Exp.cs index 6d8469dd46b..90f981a996b 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Exp.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Exp.cs @@ -5,22 +5,21 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimExp : Quantum.Intrinsic.Exp + public class QuantumProcessorDispatcherExp : Quantum.Intrinsic.Exp { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public QuantumExecutorSimExp(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherExp(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, double, IQArray), QVoid> Body => (_args) => { - var (paulis, theta, qubits) = _args; if (paulis.Length != qubits.Length) @@ -29,7 +28,7 @@ public QuantumExecutorSimExp(QuantumExecutorSimulator m) : base(m) } CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.Exp(newPaulis, theta, newQubits); + Simulator.QuantumProcessor.Exp(newPaulis, theta, newQubits); return QVoid.Instance; }; @@ -42,11 +41,10 @@ public QuantumExecutorSimExp(QuantumExecutorSimulator m) : base(m) public override Func<(IQArray, (IQArray, double, IQArray)), QVoid> ControlledBody => (_args) => { - var (ctrls, (paulis, theta, qubits)) = _args; CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.ControlledExp(ctrls, newPaulis, theta, newQubits); + Simulator.QuantumProcessor.ControlledExp(ctrls, newPaulis, theta, newQubits); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs b/src/Simulation/Simulators/QuantumProcessor/ExpFrac.cs similarity index 79% rename from src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs rename to src/Simulation/Simulators/QuantumProcessor/ExpFrac.cs index 865f4b3bc7b..5d9eda03e5a 100644 --- a/src/Simulation/Simulators/QuantumExecutor/ExpFrac.cs +++ b/src/Simulation/Simulators/QuantumProcessor/ExpFrac.cs @@ -5,19 +5,18 @@ using Microsoft.Quantum.Simulation.Core; using System; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimExpFrac : Quantum.Intrinsic.ExpFrac + public class QuantumProcessorDispatcherExpFrac : Quantum.Intrinsic.ExpFrac { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public QuantumExecutorSimExpFrac(QuantumExecutorSimulator m) : base(m) { this.Simulator = m; } + public QuantumProcessorDispatcherExpFrac(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(IQArray, long, long, IQArray), QVoid> Body => (_args) => { - var (paulis, nom, den, qubits) = _args; if (paulis.Length != qubits.Length) @@ -28,7 +27,7 @@ public class QuantumExecutorSimExpFrac : Quantum.Intrinsic.ExpFrac CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.ExpFrac(newPaulis, nom, den, newQubits); + Simulator.QuantumProcessor.ExpFrac(newPaulis, nom, den, newQubits); return QVoid.Instance; }; @@ -41,7 +40,6 @@ public class QuantumExecutorSimExpFrac : Quantum.Intrinsic.ExpFrac public override Func<(IQArray, (IQArray, long, long, IQArray)), QVoid> ControlledBody => (_args) => { - var (ctrls, (paulis, nom, den, qubits)) = _args; if (paulis.Length != qubits.Length) @@ -50,7 +48,7 @@ public class QuantumExecutorSimExpFrac : Quantum.Intrinsic.ExpFrac $"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size."); } CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - Simulator.QuantumExecutor.ControlledExpFrac(ctrls, newPaulis, nom, den, newQubits); + Simulator.QuantumProcessor.ControlledExpFrac(ctrls, newPaulis, nom, den, newQubits); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/H.cs b/src/Simulation/Simulators/QuantumProcessor/H.cs similarity index 56% rename from src/Simulation/Simulators/QuantumExecutor/H.cs rename to src/Simulation/Simulators/QuantumProcessor/H.cs index 8cbd721019c..e92bb13f6e2 100644 --- a/src/Simulation/Simulators/QuantumExecutor/H.cs +++ b/src/Simulation/Simulators/QuantumProcessor/H.cs @@ -4,33 +4,30 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimH : Quantum.Intrinsic.H + public class QuantumProcessorDispatcherH : Quantum.Intrinsic.H { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimH(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherH(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.H(q1); + Simulator.QuantumProcessor.H(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (args) => { - var (ctrls, q1) = args; - Simulator.QuantumExecutor.ControlledH(ctrls,q1); + Simulator.QuantumProcessor.ControlledH(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumProcessor/M.cs b/src/Simulation/Simulators/QuantumProcessor/M.cs new file mode 100644 index 00000000000..adf46ea18ef --- /dev/null +++ b/src/Simulation/Simulators/QuantumProcessor/M.cs @@ -0,0 +1,26 @@ +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumProcessor +{ + public partial class QuantumProcessorDispatcher + { + public class QuantumProcessorDispatcherM : Quantum.Intrinsic.M + { + private QuantumProcessorDispatcher Simulator { get; } + + public QuantumProcessorDispatcherM(QuantumProcessorDispatcher m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q) => + { + return Simulator.QuantumProcessor.M(q); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Measure.cs b/src/Simulation/Simulators/QuantumProcessor/Measure.cs similarity index 65% rename from src/Simulation/Simulators/QuantumExecutor/Measure.cs rename to src/Simulation/Simulators/QuantumProcessor/Measure.cs index 98f6a89ce4f..04b93b71162 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Measure.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Measure.cs @@ -5,16 +5,15 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimMeasure : Quantum.Intrinsic.Measure + public class QuantumProcessorDispatcherMeasure : Quantum.Intrinsic.Measure { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimMeasure(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherMeasure(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } @@ -29,7 +28,7 @@ public QuantumExecutorSimMeasure(QuantumExecutorSimulator m) : base(m) } CommonUtils.PruneObservable(paulis, qubits, out QArray newPaulis, out QArray newQubits); - return Simulator.QuantumExecutor.Measure( newPaulis, newQubits); + return Simulator.QuantumProcessor.Measure( newPaulis, newQubits); }; } } diff --git a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs similarity index 54% rename from src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs rename to src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs index 9e4024c9790..303274632f5 100644 --- a/src/Simulation/Simulators/QuantumExecutor/QuantumExecutorSimulator.cs +++ b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs @@ -4,25 +4,25 @@ using System; using Microsoft.Quantum.Simulation.Common; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { /// - /// Simulator that redirects all the calls to a class implementing interface. + /// Dispatccher (Simulator) that redirects all the calls to a class implementing interface. /// - public partial class QuantumExecutorSimulator : SimulatorBase + public partial class QuantumProcessorDispatcher : SimulatorBase { - private const int PreallocatedQubitCount = 1000; + private const int PreallocatedQubitCount = 256; /// /// Random number generator used for Microsoft.Quantum.Intrinsic.Random /// public readonly System.Random random; - public override string Name => "QuantumExecutorSimulator"; + public override string Name => "QuantumProcessorDispatcher"; /// - /// An instance of a class implementing interface that this simulator wraps. + /// An instance of a class implementing interface that this simulator wraps. /// - public IQuantumExecutor QuantumExecutor + public IQuantumProcessor QuantumProcessor { get; private set; @@ -31,18 +31,18 @@ public IQuantumExecutor QuantumExecutor /// /// /// - /// An instance of a class implementing interface to be wrapped. If the parameter is null is used. + /// An instance of a class implementing interface to be wrapped. If the parameter is null is used. /// An instance of a class implementing interface. If the parameter is null is used. /// A seed to be used by Q# Microsoft.Quantum.Intrinsic.Random operation. - public QuantumExecutorSimulator(IQuantumExecutor quantumExecutor = null, IQubitManager qubitManager = null, int? randomSeed = null) + public QuantumProcessorDispatcher(IQuantumProcessor quantumProcessor = null, IQubitManager qubitManager = null, int? randomSeed = null) : base(qubitManager ?? new QubitManagerTrackingScope(PreallocatedQubitCount, mayExtendCapacity:true, disableBorrowing:false)) { random = new System.Random(randomSeed == null ? DateTime.Now.Millisecond : randomSeed.Value); - QuantumExecutor = quantumExecutor ?? new EmptyQuantumExecutor(); - OnOperationStart += QuantumExecutor.OnOperationStart; - OnOperationEnd += QuantumExecutor.OnOperationEnd; - OnFail += QuantumExecutor.OnFail; - OnLog += QuantumExecutor.OnMessage; + QuantumProcessor = quantumProcessor ?? new EmptyQuantumProcessor(); + OnOperationStart += QuantumProcessor.OnOperationStart; + OnOperationEnd += QuantumProcessor.OnOperationEnd; + OnFail += QuantumProcessor.OnFail; + OnLog += QuantumProcessor.OnMessage; } } diff --git a/src/Simulation/Simulators/QuantumExecutor/R.cs b/src/Simulation/Simulators/QuantumProcessor/R.cs similarity index 72% rename from src/Simulation/Simulators/QuantumExecutor/R.cs rename to src/Simulation/Simulators/QuantumProcessor/R.cs index 93a91a07221..cd3307d2acf 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R.cs +++ b/src/Simulation/Simulators/QuantumProcessor/R.cs @@ -4,29 +4,27 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimR : Quantum.Intrinsic.R + public class QuantumProcessorDispatcherR : Quantum.Intrinsic.R { + private QuantumProcessorDispatcher Simulator { get; } - private QuantumExecutorSimulator Simulator { get; } - - public QuantumExecutorSimR(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherR(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Pauli, double, Qubit), QVoid> Body => (_args) => { - var (basis, angle, q1) = _args; if (basis != Pauli.PauliI) { - Simulator.QuantumExecutor.R(basis, angle,q1); + Simulator.QuantumProcessor.R(basis, angle,q1); } return QVoid.Instance; }; @@ -39,9 +37,8 @@ public QuantumExecutorSimR(QuantumExecutorSimulator m) : base(m) public override Func<(IQArray, (Pauli, double, Qubit)), QVoid> ControlledBody => (_args) => { - var (ctrls, (basis, angle, q1)) = _args; - Simulator.QuantumExecutor.ControlledR(ctrls, basis, angle, q1); + Simulator.QuantumProcessor.ControlledR(ctrls, basis, angle, q1); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/R1.cs b/src/Simulation/Simulators/QuantumProcessor/R1.cs similarity index 70% rename from src/Simulation/Simulators/QuantumExecutor/R1.cs rename to src/Simulation/Simulators/QuantumProcessor/R1.cs index 1ae4d440caa..401caf9f380 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R1.cs +++ b/src/Simulation/Simulators/QuantumProcessor/R1.cs @@ -4,27 +4,24 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimR1 : Quantum.Intrinsic.R1 + public class QuantumProcessorDispatcherR1 : Quantum.Intrinsic.R1 { + private QuantumProcessorDispatcher Simulator { get; } - private QuantumExecutorSimulator Simulator { get; } - - - public QuantumExecutorSimR1(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherR1(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(double, Qubit), QVoid> Body => (_args) => { - var (angle, q1) = _args; - Simulator.QuantumExecutor.R1(angle, q1); + Simulator.QuantumProcessor.R1(angle, q1); return QVoid.Instance; }; @@ -36,9 +33,8 @@ public QuantumExecutorSimR1(QuantumExecutorSimulator m) : base(m) public override Func<(IQArray, ( double, Qubit)), QVoid> ControlledBody => (_args) => { - var (ctrls, (angle, q1)) = _args; - Simulator.QuantumExecutor.ControlledR1(ctrls, angle, q1); + Simulator.QuantumProcessor.ControlledR1(ctrls, angle, q1); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs b/src/Simulation/Simulators/QuantumProcessor/R1Frac.cs similarity index 72% rename from src/Simulation/Simulators/QuantumExecutor/R1Frac.cs rename to src/Simulation/Simulators/QuantumProcessor/R1Frac.cs index 54b26df4b22..64808e823ad 100644 --- a/src/Simulation/Simulators/QuantumExecutor/R1Frac.cs +++ b/src/Simulation/Simulators/QuantumProcessor/R1Frac.cs @@ -5,28 +5,25 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimR1Frac : Quantum.Intrinsic.R1Frac + public class QuantumProcessorDispatcherR1Frac : Quantum.Intrinsic.R1Frac { + private QuantumProcessorDispatcher Simulator { get; } - private QuantumExecutorSimulator Simulator { get; } - - - public QuantumExecutorSimR1Frac(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherR1Frac(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(long, long, Qubit), QVoid> Body => (_args) => { - var (num, denom , q1) = _args; var (numNew, denomNew) = CommonUtils.Reduce(num, denom); - Simulator.QuantumExecutor.R1Frac(numNew, denomNew, q1); + Simulator.QuantumProcessor.R1Frac(numNew, denomNew, q1); return QVoid.Instance; }; @@ -38,10 +35,9 @@ public QuantumExecutorSimR1Frac(QuantumExecutorSimulator m) : base(m) public override Func<(IQArray, (long, long, Qubit)), QVoid> ControlledBody => (_args) => { - var (ctrls, (num, denom, q1)) = _args; var (numNew, denomNew) = CommonUtils.Reduce(num, denom); - Simulator.QuantumExecutor.ControlledR1Frac(ctrls, numNew, denomNew, q1); + Simulator.QuantumProcessor.ControlledR1Frac(ctrls, numNew, denomNew, q1); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/RFrac.cs b/src/Simulation/Simulators/QuantumProcessor/RFrac.cs similarity index 74% rename from src/Simulation/Simulators/QuantumExecutor/RFrac.cs rename to src/Simulation/Simulators/QuantumProcessor/RFrac.cs index cc7fef265d2..6164863b740 100644 --- a/src/Simulation/Simulators/QuantumExecutor/RFrac.cs +++ b/src/Simulation/Simulators/QuantumProcessor/RFrac.cs @@ -5,30 +5,28 @@ using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimRFrac : Quantum.Intrinsic.RFrac + public class QuantumProcessorDispatcherRFrac : Quantum.Intrinsic.RFrac { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimRFrac(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherRFrac(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Pauli, long, long, Qubit), QVoid> Body => (_args) => { - var (basis, num, denom , q1) = _args; if (basis != Pauli.PauliI) { var (numNew, denomNew) = CommonUtils.Reduce(num, denom); - Simulator.QuantumExecutor.RFrac(basis, numNew, denomNew, q1); + Simulator.QuantumProcessor.RFrac(basis, numNew, denomNew, q1); } return QVoid.Instance; }; @@ -41,10 +39,9 @@ public QuantumExecutorSimRFrac(QuantumExecutorSimulator m) : base(m) public override Func<(IQArray, (Pauli, long, long, Qubit)), QVoid> ControlledBody => (_args) => { - var (ctrls, (basis, num, denom, q1)) = _args; var (numNew, denomNew) = CommonUtils.Reduce(num, denom); - Simulator.QuantumExecutor.ControlledRFrac(ctrls, basis, numNew, denomNew, q1); + Simulator.QuantumProcessor.ControlledRFrac(ctrls, basis, numNew, denomNew, q1); return QVoid.Instance; }; diff --git a/src/Simulation/Simulators/QuantumExecutor/Release.cs b/src/Simulation/Simulators/QuantumProcessor/Release.cs similarity index 50% rename from src/Simulation/Simulators/QuantumExecutor/Release.cs rename to src/Simulation/Simulators/QuantumProcessor/Release.cs index 4aa94ffa091..84424d3daa0 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Release.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Release.cs @@ -3,26 +3,26 @@ using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimRelease : Intrinsic.Release + public class QuantumProcessorDispatcherRelease : Intrinsic.Release { - private readonly QuantumExecutorSimulator sim; - public QuantumExecutorSimRelease(QuantumExecutorSimulator m) : base(m){ + private readonly QuantumProcessorDispatcher sim; + public QuantumProcessorDispatcherRelease(QuantumProcessorDispatcher m) : base(m){ sim = m; } public override void Apply(Qubit q) { - sim.QuantumExecutor.OnReleaseQubits(new QArray(q)); + sim.QuantumProcessor.OnReleaseQubits(new QArray(q)); sim.QubitManager.Release(q); } public override void Apply(IQArray qubits) { - sim.QuantumExecutor.OnReleaseQubits(qubits); + sim.QuantumProcessor.OnReleaseQubits(qubits); sim.QubitManager.Release(qubits); } } diff --git a/src/Simulation/Simulators/QuantumProcessor/Reset.cs b/src/Simulation/Simulators/QuantumProcessor/Reset.cs new file mode 100644 index 00000000000..4ebee59437a --- /dev/null +++ b/src/Simulation/Simulators/QuantumProcessor/Reset.cs @@ -0,0 +1,27 @@ +ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.QuantumProcessor +{ + public partial class QuantumProcessorDispatcher + { + public class QuantumProcessorDispatcherReset : Quantum.Intrinsic.Reset + { + private QuantumProcessorDispatcher Simulator { get; } + + public QuantumProcessorDispatcherReset(QuantumProcessorDispatcher m) : base(m) + { + this.Simulator = m; + } + + public override Func Body => (q1) => + { + Simulator.QuantumProcessor.Reset(q1); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumExecutor/Return.cs b/src/Simulation/Simulators/QuantumProcessor/Return.cs similarity index 50% rename from src/Simulation/Simulators/QuantumExecutor/Return.cs rename to src/Simulation/Simulators/QuantumProcessor/Return.cs index 743ddfeb8d8..db541624ef3 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Return.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Return.cs @@ -1,28 +1,28 @@ ο»Ώ// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { using Microsoft.Quantum.Simulation.Core; - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimReturn : Intrinsic.Return + public class QuantumProcessorDispatcherReturn : Intrinsic.Return { - private readonly QuantumExecutorSimulator sim; - public QuantumExecutorSimReturn(QuantumExecutorSimulator m) : base(m){ + private readonly QuantumProcessorDispatcher sim; + public QuantumProcessorDispatcherReturn(QuantumProcessorDispatcher m) : base(m){ sim = m; } public override void Apply(Qubit q) { - sim.QuantumExecutor.OnReturnQubits(new QArray(q)); + sim.QuantumProcessor.OnReturnQubits(new QArray(q)); sim.QubitManager.Return(q); } public override void Apply(IQArray qubits) { - sim.QuantumExecutor.OnReturnQubits(qubits); + sim.QuantumProcessor.OnReturnQubits(qubits); sim.QubitManager.Return(qubits); } } diff --git a/src/Simulation/Simulators/QuantumExecutor/S.cs b/src/Simulation/Simulators/QuantumProcessor/S.cs similarity index 62% rename from src/Simulation/Simulators/QuantumExecutor/S.cs rename to src/Simulation/Simulators/QuantumProcessor/S.cs index 1d8812df8d7..84bac1a1ed9 100644 --- a/src/Simulation/Simulators/QuantumExecutor/S.cs +++ b/src/Simulation/Simulators/QuantumProcessor/S.cs @@ -4,46 +4,42 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimS : Quantum.Intrinsic.S + public class QuantumProcessorDispatcherS : Quantum.Intrinsic.S { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public QuantumExecutorSimS(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherS(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.S(q1); + Simulator.QuantumProcessor.S(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledS(ctrls, q1); + Simulator.QuantumProcessor.ControlledS(ctrls, q1); return QVoid.Instance; }; public override Func AdjointBody => (q1) => { - - Simulator.QuantumExecutor.SAdj(q1); + Simulator.QuantumProcessor.SAdjoint(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledSAdj(ctrls, q1); + Simulator.QuantumProcessor.ControlledSAdjoint(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/SWAP.cs b/src/Simulation/Simulators/QuantumProcessor/SWAP.cs similarity index 55% rename from src/Simulation/Simulators/QuantumExecutor/SWAP.cs rename to src/Simulation/Simulators/QuantumProcessor/SWAP.cs index 7b96ecf6e73..edb95bf4c63 100644 --- a/src/Simulation/Simulators/QuantumExecutor/SWAP.cs +++ b/src/Simulation/Simulators/QuantumProcessor/SWAP.cs @@ -4,32 +4,29 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimSWAP : Quantum.Intrinsic.SWAP + public class QuantumProcessorDispatcherSWAP : Quantum.Intrinsic.SWAP { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimSWAP(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherSWAP(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func<(Qubit,Qubit), QVoid> Body => (q1) => { - - Simulator.QuantumExecutor.SWAP(q1.Item1, q1.Item2); + Simulator.QuantumProcessor.SWAP(q1.Item1, q1.Item2); return QVoid.Instance; }; public override Func<(IQArray, (Qubit, Qubit)), QVoid> ControlledBody => (args) => { - var (ctrls, q1) = args; - Simulator.QuantumExecutor.ControlledSWAP(ctrls, q1.Item1, q1.Item2); + Simulator.QuantumProcessor.ControlledSWAP(ctrls, q1.Item1, q1.Item2); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/T.cs b/src/Simulation/Simulators/QuantumProcessor/T.cs similarity index 62% rename from src/Simulation/Simulators/QuantumExecutor/T.cs rename to src/Simulation/Simulators/QuantumProcessor/T.cs index 55ecdfde021..e7d7e295ac4 100644 --- a/src/Simulation/Simulators/QuantumExecutor/T.cs +++ b/src/Simulation/Simulators/QuantumProcessor/T.cs @@ -4,49 +4,44 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimT : Quantum.Intrinsic.T + public class QuantumProcessorDispatcherT : Quantum.Intrinsic.T { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimT(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherT(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.T(q1); + Simulator.QuantumProcessor.T(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledT(ctrls, q1); + Simulator.QuantumProcessor.ControlledT(ctrls, q1); return QVoid.Instance; }; public override Func AdjointBody => (q1) => { - - Simulator.QuantumExecutor.TAdj(q1); + Simulator.QuantumProcessor.TAdjoint(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledTAdj(ctrls, q1); + Simulator.QuantumProcessor.ControlledTAdjoint(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/X.cs b/src/Simulation/Simulators/QuantumProcessor/X.cs similarity index 56% rename from src/Simulation/Simulators/QuantumExecutor/X.cs rename to src/Simulation/Simulators/QuantumProcessor/X.cs index a65e19d62b0..1de39069395 100644 --- a/src/Simulation/Simulators/QuantumExecutor/X.cs +++ b/src/Simulation/Simulators/QuantumProcessor/X.cs @@ -4,32 +4,29 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimX : Quantum.Intrinsic.X + public class QuantumProcessorDispatcherX : Quantum.Intrinsic.X { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimX(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherX(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.X(q1); + Simulator.QuantumProcessor.X(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (args) => { - var (ctrls, q1) = args; - Simulator.QuantumExecutor.ControlledX(ctrls, q1); + Simulator.QuantumProcessor.ControlledX(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/Y.cs b/src/Simulation/Simulators/QuantumProcessor/Y.cs similarity index 58% rename from src/Simulation/Simulators/QuantumExecutor/Y.cs rename to src/Simulation/Simulators/QuantumProcessor/Y.cs index bc64eb27500..e4a7836c7d5 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Y.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Y.cs @@ -4,32 +4,29 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimY : Quantum.Intrinsic.Y + public class QuantumProcessorDispatcherY : Quantum.Intrinsic.Y { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - - public QuantumExecutorSimY(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherY(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.Y(q1); + Simulator.QuantumProcessor.Y(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledY(ctrls, q1); + Simulator.QuantumProcessor.ControlledY(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/Z.cs b/src/Simulation/Simulators/QuantumProcessor/Z.cs similarity index 57% rename from src/Simulation/Simulators/QuantumExecutor/Z.cs rename to src/Simulation/Simulators/QuantumProcessor/Z.cs index 2e7c3646e71..b939d1373ef 100644 --- a/src/Simulation/Simulators/QuantumExecutor/Z.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Z.cs @@ -4,31 +4,29 @@ using System; using Microsoft.Quantum.Simulation.Core; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { - public class QuantumExecutorSimZ : Quantum.Intrinsic.Z + public class QuantumProcessorDispatcherZ : Quantum.Intrinsic.Z { - private QuantumExecutorSimulator Simulator { get; } + private QuantumProcessorDispatcher Simulator { get; } - public QuantumExecutorSimZ(QuantumExecutorSimulator m) : base(m) + public QuantumProcessorDispatcherZ(QuantumProcessorDispatcher m) : base(m) { this.Simulator = m; } public override Func Body => (q1) => { - - Simulator.QuantumExecutor.Z(q1); + Simulator.QuantumProcessor.Z(q1); return QVoid.Instance; }; public override Func<(IQArray, Qubit), QVoid> ControlledBody => (_args) => { - (IQArray ctrls, Qubit q1) = _args; - Simulator.QuantumExecutor.ControlledZ(ctrls, q1); + Simulator.QuantumProcessor.ControlledZ(ctrls, q1); return QVoid.Instance; }; } diff --git a/src/Simulation/Simulators/QuantumExecutor/random.cs b/src/Simulation/Simulators/QuantumProcessor/random.cs similarity index 81% rename from src/Simulation/Simulators/QuantumExecutor/random.cs rename to src/Simulation/Simulators/QuantumProcessor/random.cs index 38350175bad..d9c51cfa202 100644 --- a/src/Simulation/Simulators/QuantumExecutor/random.cs +++ b/src/Simulation/Simulators/QuantumProcessor/random.cs @@ -4,9 +4,9 @@ using Microsoft.Quantum.Simulation.Core; using System; -namespace Microsoft.Quantum.Simulation.QuantumExecutor +namespace Microsoft.Quantum.Simulation.QuantumProcessor { - public partial class QuantumExecutorSimulator + public partial class QuantumProcessorDispatcher { public static long SampleDistribution(IQArray unnormalizedDistribution, double uniformZeroOneSample) { @@ -38,10 +38,10 @@ public static long SampleDistribution(IQArray unnormalizedDistribution, return unnormalizedDistribution.Length; } - public class QuantumExecutorSimRandom : Quantum.Intrinsic.Random + public class QuantumProcessorDispatcherRandom : Quantum.Intrinsic.Random { - private QuantumExecutorSimulator Simulator { get; } - public QuantumExecutorSimRandom(QuantumExecutorSimulator m) : base(m) + private QuantumProcessorDispatcher Simulator { get; } + public QuantumProcessorDispatcherRandom(QuantumProcessorDispatcher m) : base(m) { Simulator = m; } From 7f6d97bb291e895fe2e7ee6d719827a6c98baaa8 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Fri, 22 Nov 2019 19:53:42 -0800 Subject: [PATCH 06/12] Fix --- src/Simulation/Common/EmptyQuantumProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulation/Common/EmptyQuantumProcessor.cs b/src/Simulation/Common/EmptyQuantumProcessor.cs index 8fc430ec515..a93482428f9 100644 --- a/src/Simulation/Common/EmptyQuantumProcessor.cs +++ b/src/Simulation/Common/EmptyQuantumProcessor.cs @@ -10,7 +10,7 @@ namespace Microsoft.Quantum.Simulation.Common /// A class that implements IQuantumProcessor that does not do any logic, but is convenient to inherit from. /// It throws for most APIs. /// - class EmptyQuantumProcessor : IQuantumProcessor + public class EmptyQuantumProcessor : IQuantumProcessor { public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) { From e6e104f86dc23bc8ae7f0aca204a79ce2ee01089 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Mon, 25 Nov 2019 11:36:39 -0800 Subject: [PATCH 07/12] CLassical control default for simulators --- .../Common/EmptyQuantumProcessor.cs | 31 +++++++++++++++++-- src/Simulation/Core/QArray.cs | 4 ++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Simulation/Common/EmptyQuantumProcessor.cs b/src/Simulation/Common/EmptyQuantumProcessor.cs index a93482428f9..d2f28097447 100644 --- a/src/Simulation/Common/EmptyQuantumProcessor.cs +++ b/src/Simulation/Common/EmptyQuantumProcessor.cs @@ -3,6 +3,7 @@ using System; using Microsoft.Quantum.Simulation.Core; +using System.Diagnostics; namespace Microsoft.Quantum.Simulation.Common { @@ -22,12 +23,38 @@ public virtual void AssertProb(IQArray bases, IQArray qubits, doub public virtual void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne) { - throw new NotImplementedException(); + if (measurementResult == Result.Zero) + { + onZero(); + } + else + { + onOne(); + } } public virtual void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp) { - throw new NotImplementedException(); + Debug.Assert(measurementResults.Count == resultsValues.Count); + + bool equal = true; + + for (int i = 0; i < measurementResults.Count; i++) + { + if (measurementResults[i] != resultsValues[i]) + { + equal = false; + } + } + + if (equal) + { + equalOp(); + } + else + { + nonEqualOp(); + } } public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) diff --git a/src/Simulation/Core/QArray.cs b/src/Simulation/Core/QArray.cs index 450fb93253a..d536497bb4e 100644 --- a/src/Simulation/Core/QArray.cs +++ b/src/Simulation/Core/QArray.cs @@ -329,6 +329,7 @@ IEnumerable IApplyData.Qubits /// and ArgumentOutOfRangeException. /// /// The long index of the element to access + /// New value of the element /// The element public QArray Modify(long index, T value) { @@ -351,7 +352,8 @@ public QArray Modify(long index, T value) /// or if an index is outside the array bounds, it throws /// and ArgumentOutOfRangeException. /// - /// The long index of the element to access + /// The range of indices of the elements to access + /// New values of the elements /// The element public QArray Modify(QRange indices, IQArray values) { From de61b8d25ee8eeb5932b2df5b3f0df747a6d2ea2 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Mon, 25 Nov 2019 15:47:27 -0800 Subject: [PATCH 08/12] More documentation --- src/Simulation/Common/IQuantumProcessor.cs | 2 +- .../{EmptyQuantumProcessor.cs => QuantumProcessorBase.cs} | 2 +- src/Simulation/Core/QArray.cs | 2 +- .../Simulators/QuantumProcessor/ClassicalControl.qs | 8 ++++++++ .../QuantumProcessor/QuantumProcessorDispatcher.cs | 4 ++-- 5 files changed, 13 insertions(+), 5 deletions(-) rename src/Simulation/Common/{EmptyQuantumProcessor.cs => QuantumProcessorBase.cs} (99%) diff --git a/src/Simulation/Common/IQuantumProcessor.cs b/src/Simulation/Common/IQuantumProcessor.cs index 32781accc87..c5fac494250 100644 --- a/src/Simulation/Common/IQuantumProcessor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -11,7 +11,7 @@ namespace Microsoft.Quantum.Simulation.Common /// /// /// To implement a target machine that executes quantum commands, implement this interface. - /// Consider using as a stub for easy impementation of this interface. + /// Consider using as a stub for easy impementation of this interface. /// Implementors of interface do not manage qubits on their own. /// All qubit management (allocation, dealocation, etc.) is done by the caller of this interface. /// Implementors are notified when qubits are allocated, released, borrowed and returned allowing them to react to these events if necessary. diff --git a/src/Simulation/Common/EmptyQuantumProcessor.cs b/src/Simulation/Common/QuantumProcessorBase.cs similarity index 99% rename from src/Simulation/Common/EmptyQuantumProcessor.cs rename to src/Simulation/Common/QuantumProcessorBase.cs index d2f28097447..46f135e7558 100644 --- a/src/Simulation/Common/EmptyQuantumProcessor.cs +++ b/src/Simulation/Common/QuantumProcessorBase.cs @@ -11,7 +11,7 @@ namespace Microsoft.Quantum.Simulation.Common /// A class that implements IQuantumProcessor that does not do any logic, but is convenient to inherit from. /// It throws for most APIs. /// - public class EmptyQuantumProcessor : IQuantumProcessor + public class QuantumProcessorBase : IQuantumProcessor { public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) { diff --git a/src/Simulation/Core/QArray.cs b/src/Simulation/Core/QArray.cs index d536497bb4e..de9db576c88 100644 --- a/src/Simulation/Core/QArray.cs +++ b/src/Simulation/Core/QArray.cs @@ -568,7 +568,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s } /// - /// Reads the QArray<> + /// Reads the /// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { diff --git a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs index 20810640212..f9bd481641d 100644 --- a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs +++ b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.qs @@ -72,6 +72,8 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions // Public operations that match Canon names. + // This corresponds to "if" statement of the following form in Q#: + // if (measurementResult == Zero) {onResultZeroOp(zeroArg);} else {onResultOneOp(oneArg);} operation ApplyIfElseR<'T,'U>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T) , (onResultOneOp : ('U => Unit), oneArg : 'U)) : Unit { let zeroOp = Delay(onResultZeroOp, zeroArg, _); let oneOp = Delay(onResultOneOp, oneArg, _); @@ -98,6 +100,8 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions // Public operations that match Canon names. + // This corresponds to "if" statement of the following form in Q#: + // if (measurementResult == Zero) {onResultZeroOp(zeroArg);} operation ApplyIfZero<'T>(measurementResult : Result, (onResultZeroOp : ('T => Unit), zeroArg : 'T)) : Unit { let zeroOp = Delay(onResultZeroOp, zeroArg, _); let oneOp = Delay(NoOp, (), _); @@ -124,6 +128,8 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions // Public operations that match Canon names. + // This corresponds to "if" statement of the following form in Q#: + // if (measurementResult == One) {onResultOneOp(oneArg);} operation ApplyIfOne<'T>(measurementResult : Result, (onResultOneOp : ('T => Unit), oneArg : 'T)) : Unit { let oneOp = Delay(onResultOneOp, oneArg, _); let zeroOp = Delay(NoOp, (), _); @@ -150,6 +156,8 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions // Public operations that match Canon names. + // This corresponds to "if" statement of the following form in Q#: + // if ((measurementResults[0] == resultsValues[0]) && (measurementResults[1] == resultsValues[1])) {onEqualOp(equalArg);} else {onNonEqualOp(nonEqualArg);} operation ApplyConditionally<'T,'U>(measurementResults : Result[], resultsValues : Result[], (onEqualOp : ('T => Unit), equalArg : 'T) , (onNonEqualOp : ('U => Unit), nonEqualArg : 'U)) : Unit { let equalOp = Delay(onEqualOp,equalArg,_); let nonEqualOp = Delay(onNonEqualOp,nonEqualArg,_); diff --git a/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs index 303274632f5..43adcfe7921 100644 --- a/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs +++ b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs @@ -31,14 +31,14 @@ public IQuantumProcessor QuantumProcessor /// /// /// - /// An instance of a class implementing interface to be wrapped. If the parameter is null is used. + /// An instance of a class implementing interface to be wrapped. If the parameter is null is used. /// An instance of a class implementing interface. If the parameter is null is used. /// A seed to be used by Q# Microsoft.Quantum.Intrinsic.Random operation. public QuantumProcessorDispatcher(IQuantumProcessor quantumProcessor = null, IQubitManager qubitManager = null, int? randomSeed = null) : base(qubitManager ?? new QubitManagerTrackingScope(PreallocatedQubitCount, mayExtendCapacity:true, disableBorrowing:false)) { random = new System.Random(randomSeed == null ? DateTime.Now.Millisecond : randomSeed.Value); - QuantumProcessor = quantumProcessor ?? new EmptyQuantumProcessor(); + QuantumProcessor = quantumProcessor ?? new QuantumProcessorBase(); OnOperationStart += QuantumProcessor.OnOperationStart; OnOperationEnd += QuantumProcessor.OnOperationEnd; OnFail += QuantumProcessor.OnFail; From b74314b78e1d2323764459356b80dc9c01107db2 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Fri, 6 Dec 2019 14:40:03 -0800 Subject: [PATCH 09/12] Documentation fixes --- src/Simulation/Common/IQuantumProcessor.cs | 70 +++++++++---------- .../QuantumProcessorDispatcher.cs | 2 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Simulation/Common/IQuantumProcessor.cs b/src/Simulation/Common/IQuantumProcessor.cs index c5fac494250..30a36bb277f 100644 --- a/src/Simulation/Common/IQuantumProcessor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -20,7 +20,7 @@ public interface IQuantumProcessor { /// /// Called when Microsoft.Quantum.Intrinsic.X is called in Q#. - /// In Q# the operation applies X gate to . The gate is given by matrix X=((0,1),(1,0)). + /// When this is invoked, it is expected that the X gate gets applied to the given . The gate is given by matrix X=((0,1),(1,0)). /// /// /// When adjoint of X is called in Q#, this same method is called because X is self-adjoint. @@ -31,7 +31,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.X is called in Q#. - /// In Q# the operation applies X gate to controlled on . The gate is given by matrix X=((0,1),(1,0)). + /// When this is invoked, it is expected that the X gate gets applied to the given controlled on . The gate is given by matrix X=((0,1),(1,0)). /// /// /// When adjoint of Controlled X is called in Q#, this same method is called because X is self-adjoint. @@ -43,7 +43,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.Y is called in Q#. - /// In Q# the operation applies Y gate to . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// When this is invoked, it is expected that the Y gate gets applied to the given . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// /// When adjoint of Y is called in Q#, this same method is called because Y is self-adjoint. @@ -54,7 +54,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.Y is called in Q#. - /// In Q# the operation applies X gate to controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). + /// When this is invoked, it is expected that the Y gate gets applied to the given controlled on . The gate is given by matrix Y=((0,-𝑖),(𝑖,0)). /// /// /// When adjoint of Controlled Y is called in Q#, this same method is called because Y is self-adjoint. @@ -66,7 +66,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.Z is called in Q#. - /// In Q# the operation applies Z gate to . The gate is given by matrix Z=((1,0),(0,-1)). + /// When this is invoked, it is expected that the Z gate gets applied to the given . The gate is given by matrix Z=((1,0),(0,-1)). /// /// /// When adjoint of Z is called in Q#, this same method is called because Z is self-adjoint. @@ -77,7 +77,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.Z is called in Q#. - /// In Q# the operation applies Z gate to controlled on . The gate is given by matrix Z=((1,0),(0,-1)). + /// When this is invoked, it is expected that the Z gate gets applied to the given controlled on . The gate is given by matrix Z=((1,0),(0,-1)). /// /// /// When adjoint of Controlled Z is called in Q#, this same method is called because Z is self-adjoint. @@ -89,7 +89,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.SWAP is called in Q#. - /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states. + /// When this is invoked, it is expected that the gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states gets applied. /// /// /// When adjoint of SWAP is called in Q#, this same method is called because SWAP is self-adjoint. @@ -101,7 +101,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.SWAP is called in Q#. - /// In Q# the operation applies gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states controlled on . + /// When this is invoked, it is expected that the gate given by rule |ΟˆβŸ©βŠ—|Ο•βŸ© ↦ |Ο•βŸ©βŠ—|ψ⟩ where |Ο•βŸ©,|ψ⟩ arbitrary one qubit states gets applied, controlled on . /// /// /// When adjoint of Controlled SWAP is called in Q#, this same method is called because SWAP is self-adjoint. @@ -114,7 +114,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.H is called in Q#. - /// In Q# the operation applies Hadamard gate to . The gate is given by matrix H=((1,1),(1,-1))/√2. + /// When this is invoked, it is expected that the Hadamard gate gets applied to . The gate is given by matrix H=((1,1),(1,-1))/√2. /// /// /// When adjoint of H is called in Q#, this same method is called because Hadamard is self-adjoint. @@ -125,7 +125,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.H is called in Q#. - /// In Q# the operation applies Hadamard gate to controlled on . The gate is given by matrix H=((1,1),(1,-1))/√2. + /// When this is invoked, it is expected that the Hadamard gate gets applied to controlled on . The gate is given by matrix H=((1,1),(1,-1))/√2. /// /// /// When adjoint of Controlled H is called in Q#, this same method is called because Hadamard is self-adjoint. @@ -137,7 +137,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.S is called in Q#. - /// In Q# the operation applies S gate to . The gate is given by matrix S=((1,0),(0,𝑖)). + /// When this is invoked, it is expected that the S gate gets applied to . The gate is given by matrix S=((1,0),(0,𝑖)). /// /// /// When adjoint of S is called in Q#, is called. @@ -148,7 +148,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.S is called in Q#. - /// In Q# the operation applies S gate to controlled on . The gate is given by matrix S=((1,0),(0,𝑖)). + /// When this is invoked, it is expected that the S gate gets applied to controlled on . The gate is given by matrix S=((1,0),(0,𝑖)). /// /// /// When adjoint of Controlled S is called in Q#, is called. @@ -160,7 +160,7 @@ public interface IQuantumProcessor /// /// Called when adjoint Microsoft.Quantum.Intrinsic.S is called in Q#. - /// In Q# the operation applies S† gate to . The gate is given by matrix S†=((1,0),(0,-𝑖)). + /// When this is invoked, it is expected that the S† gate gets applied to . The gate is given by matrix S†=((1,0),(0,-𝑖)). /// /// /// When adjoint of Adjoint S is called in Q#, is called. @@ -171,7 +171,7 @@ public interface IQuantumProcessor /// /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.S is called in Q#. - /// In Q# the operation applies S† gate to controlled on . The gate is given by matrix S†=((1,0),(0,𝑖)). + /// When this is invoked, it is expected that the S† gate gets applied to controlled on . The gate is given by matrix S†=((1,0),(0,𝑖)). /// /// /// When adjoint of Controlled S† is called in Q#, is called. @@ -183,7 +183,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.T is called in Q#. - /// In Q# the operation applies T gate to . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). + /// When this is invoked, it is expected that the T gate gets applied to . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). /// /// /// When adjoint of T is called in Q#, is called. @@ -194,7 +194,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.T is called in Q#. - /// In Q# the operation applies T gate to controlled on . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). + /// When this is invoked, it is expected that the T gate gets applied to controlled on . The gate is given by matrix T=((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π/4))). /// /// /// When adjoint of Controlled T is called in Q#, is called. @@ -206,7 +206,7 @@ public interface IQuantumProcessor /// /// Called when adjoint Microsoft.Quantum.Intrinsic.T is called in Q#. - /// In Q# the operation applies T† gate to . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). + /// When this is invoked, it is expected that the T† gate gets applied to . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). /// /// /// When adjoint of Adjoint T is called in Q#, is called. @@ -217,7 +217,7 @@ public interface IQuantumProcessor /// /// Called when controlled adjoint Microsoft.Quantum.Intrinsic.T is called in Q#. - /// In Q# the operation applies T† gate to controlled on . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). + /// When this is invoked, it is expected that the T† gate gets applied to controlled on . The gate is given by matrix T†=((1,0),(0,𝑒π‘₯𝑝(-𝑖⋅π/4))). /// /// /// When adjoint of Controlled T† is called in Q#, is called. @@ -229,7 +229,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(-𝑖⋅⋅/2) gets applied to . /// /// /// When adjoint of R is called in Q#, is called with replaced by -. @@ -242,7 +242,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(-𝑖⋅⋅/2) to controlled on . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(-𝑖⋅⋅/2) gets applied to controlled on . /// /// /// When adjoint of Controlled R is called in Q#, is called with replaced by -. @@ -256,7 +256,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.RFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) gets applied to . /// /// /// When adjoint of RFrac is called in Q#, is called with replaced by -. @@ -270,7 +270,7 @@ public interface IQuantumProcessor /// /// Called when a controlled Microsoft.Quantum.Intrinsic.RFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) gets applied to controlled on . /// /// /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. @@ -285,7 +285,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.R1 is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to . + /// When this is invoked, it is expected that the gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) gets applied to . /// /// /// When adjoint of R1 is called in Q#, is called with replaced by -. @@ -297,7 +297,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.R is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) to controlled on . + /// When this is invoked, it is expected that the gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅))) gets applied to controlled on . /// /// /// When adjoint of Controlled R1 is called in Q#, is called with replaced by -. @@ -310,7 +310,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to . + /// When this is invoked, it is expected that the gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) gets applied to . /// /// /// When adjoint of R1Frac is called in Q#, is called with replaced by -. @@ -323,7 +323,7 @@ public interface IQuantumProcessor /// /// Called when a controlled Microsoft.Quantum.Intrinsic.R1Frac is called in Q#. - /// In Q# the operation applies gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) to controlled on . + /// When this is invoked, it is expected that the gate given by matrix ((1,0),(0,𝑒π‘₯𝑝(𝑖⋅π⋅/2^))) gets applied to controlled on . /// /// /// When adjoint of Controlled RFrac is called in Q#, is called with replaced by -. @@ -337,7 +337,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.Exp is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅⋅) gets applied to . /// /// /// When adjoint of Exp is called in Q#, is called with replaced by -. @@ -350,7 +350,7 @@ public interface IQuantumProcessor /// /// Called when a controlled Microsoft.Quantum.Intrinsic.Exp is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅⋅) to controlled on . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅⋅) gets applied to controlled on . /// /// /// When adjoint of Controlled Exp is called in Q#, is called with replaced by -. @@ -364,7 +364,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) gets applied to . /// /// /// When adjoint of ExpFrac is called in Q#, is called with replaced by -. @@ -378,7 +378,7 @@ public interface IQuantumProcessor /// /// Called when controlled Microsoft.Quantum.Intrinsic.ExpFrac is called in Q#. - /// In Q# the operation applies 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) to controlled on . + /// When this is invoked, it is expected that the 𝑒π‘₯𝑝(𝑖⋅π⋅⋅/2^) gets applied to controlled on . /// /// /// When adjoint of Controlled ExpFrac is called in Q#, is called with replaced by -. @@ -393,7 +393,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.M is called in Q#. - /// In Q# the operation measures in Z basis, in other words in the computational basis. + /// When this is invoked, it is expected that the is measured in Z basis, in other words in the computational basis. /// /// /// The names and the order of the parameters are the same as for the corresponding Q# operation. @@ -405,7 +405,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.Measure is called in Q#. - /// In Q# the operation measures multi-qubit Pauli observable given by on . + /// When this is invoked, it is expected that the multi-qubit Pauli observable given by is measured on . /// /// /// The names and the order of the parameters are the same as for the corresponding Q# operation. @@ -418,7 +418,7 @@ public interface IQuantumProcessor /// /// Called when Microsoft.Quantum.Intrinsic.Reset is called in Q#. - /// In Q# the operation, measures and ensures it is in the |0⟩ state such that it can be safely released. + /// When this is invoked, it is expected that the is measured and ensured to be in the |0⟩ state such that it can be safely released. /// /// /// The names and the order of the parameters are the same as for the corresponding Q# operation. @@ -434,7 +434,7 @@ public interface IQuantumProcessor /// Corresponds to quantum program that must be executed if result is /// /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. + /// The program is executed within the same instance of interface. /// void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); @@ -447,7 +447,7 @@ public interface IQuantumProcessor /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding /// /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed with the same instance of interface. + /// The program is executed within the same instance of interface. /// void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); diff --git a/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs index 43adcfe7921..54d937add40 100644 --- a/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs +++ b/src/Simulation/Simulators/QuantumProcessor/QuantumProcessorDispatcher.cs @@ -7,7 +7,7 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor { /// - /// Dispatccher (Simulator) that redirects all the calls to a class implementing interface. + /// Dispatcher (Simulator) that redirects all the calls to a class implementing interface. /// public partial class QuantumProcessorDispatcher : SimulatorBase { From bbe70c941086cb2c3c53f83c408d1bf8b96cbe81 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Thu, 12 Dec 2019 19:34:34 -0800 Subject: [PATCH 10/12] Clasical Control interface changed to avoid passing in pointers to functions. --- src/Simulation/Common/IQuantumProcessor.cs | 79 ++++++-- src/Simulation/Common/QuantumProcessorBase.cs | 58 ++++-- .../QuantumProcessor/ClassicalControl.cs | 172 ++++++++++-------- 3 files changed, 204 insertions(+), 105 deletions(-) diff --git a/src/Simulation/Common/IQuantumProcessor.cs b/src/Simulation/Common/IQuantumProcessor.cs index 30a36bb277f..3e8ca1d0534 100644 --- a/src/Simulation/Common/IQuantumProcessor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -428,28 +428,81 @@ public interface IQuantumProcessor /// /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when a conditional statement on measurement results is invoked. /// - /// The result of the measurement upon which branching is to be performed. - /// Corresponds to quantum program that must be executed if result is - /// Corresponds to quantum program that must be executed if result is + /// The actual results of the measurements of a number of qubits upon which branching is to be performed. + /// The expected values of results of the measurements of these qubits. + /// A value representing this conditional statement and encoding the result of condition. /// - /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed within the same instance of interface. + /// A typical implementation will compare all to and return the result of this comparison. /// - void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne); + int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues); /// /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when a conditional statement on a measurement result is invoked. /// - /// The actual results of the measurements of a number of qubits upon which branching is to be performed. - /// The expected values of results of the measurements of these qubits. - /// Corresponds to quantum program that must be executed if all values are equal to corresponding - /// Corresponds to quantum program that must be executed if at least one of the values is not equal to a corresponding + /// The actual result of the measurement of a qubit upon which branching is to be performed. + /// The expected value of result of the measurement of this qubit. + /// A value representing this conditional statement and encoding the result of condition. + /// + /// A typical implementation will compare to and return the result of this comparison. + /// + int StartConditionalStatement(Result measurementResult, Result resultValue); + + /// + /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when the "then" statement of a conditional statement is about to be executed. + /// + /// A value representing this conditional statement and encoding the result of condition. + /// If true is returned, the "then" statement will be executed, otherwise it will be skipped and RepeatThenClause will not be called. + /// + /// A typical implementation will use to return whether condition was evaluated to true. + /// + bool RunThenClause(int statement); + + /// + /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when the "then" statement of a conditional statement has finished executing. + /// + /// A value representing this conditional statement and encoding the result of condition. + /// If true is returned, the "then" statement will be executed again (without calling RunThenClause), folowed by another call to RepeatThenClause. + /// + /// A typical implementation will return false. + /// + bool RepeatThenClause(int statement); + + /// + /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when the "else" statement of a conditional statement is about to be executed. + /// + /// A value representing this conditional statement and encoding the result of condition. + /// If true is returned, the "else" statement will be executed, otherwise it will be skipped and RepeatElseClause will not be called. + /// + /// A typical implementation will use to return whether condition was evaluated to false. + /// + bool RunElseClause(int statement); + + /// + /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when the "else" statement of a conditional statement has finished executing. + /// + /// A value representing this conditional statement and encoding the result of condition. + /// If true is returned, the "else" statement will be executed again (without calling RunElseClause), folowed by another call to RepeatElseClause. + /// + /// A typical implementation will return false. + /// + bool RepeatElseClause(int statement); + + /// + /// Intended for a limited support of branching upon measurement results on a target machine level. + /// Called when a conditional statement on measurement results has finished executing. + /// + /// A value representing this conditional statement and encoding the result of condition. /// - /// Calling onZero() will result in the execution of quantum program that Q# user intends to execute if result is . - /// The program is executed within the same instance of interface. + /// A typical implementation will clean up any data structures associated with statement. /// - void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp); + void EndConditionalStatement(int statement); /// /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. diff --git a/src/Simulation/Common/QuantumProcessorBase.cs b/src/Simulation/Common/QuantumProcessorBase.cs index 46f135e7558..68fec627b64 100644 --- a/src/Simulation/Common/QuantumProcessorBase.cs +++ b/src/Simulation/Common/QuantumProcessorBase.cs @@ -21,42 +21,60 @@ public virtual void AssertProb(IQArray bases, IQArray qubits, doub { } - public virtual void ClassicallyControlled(Result measurementResult, Action onZero, Action onOne) - { - if (measurementResult == Result.Zero) - { - onZero(); - } - else - { - onOne(); - } - } - - public virtual void ClassicallyControlled(IQArray measurementResults, IQArray resultsValues, Action equalOp, Action nonEqualOp) + public virtual int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues) { Debug.Assert(measurementResults.Count == resultsValues.Count); - bool equal = true; + int equal = 1; for (int i = 0; i < measurementResults.Count; i++) { if (measurementResults[i] != resultsValues[i]) { - equal = false; + equal = 0; } } - if (equal) + return equal; + } + + public virtual int StartConditionalStatement(Result measurementResult, Result resultValue) + { + + if (measurementResult == resultValue) { - equalOp(); - } - else + return 1; + } else { - nonEqualOp(); + return 0; } } + public virtual bool RunThenClause(int statement) + { + return (statement != 0); + } + + public virtual bool RepeatThenClause(int statement) + { + return false; + } + + public virtual bool RunElseClause(int statement) + { + return (statement == 0); + } + + public virtual bool RepeatElseClause(int statement) + { + return false; + } + + public virtual void EndConditionalStatement(int id) + { + + } + public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) { throw new NotImplementedException(); diff --git a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs index aa799e79c91..7113456f977 100644 --- a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs +++ b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs @@ -8,6 +8,88 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor { public partial class QuantumProcessorDispatcher { + private enum FunctorType + { + Body, + Adjoint, + Controlled, + AdjointControlled, + } + + private static void RunClause(ICallable op, FunctorType type, IQArray ctrls) + { + switch (type) + { + case FunctorType.Body: op.Apply(QVoid.Instance); break; + case FunctorType.Adjoint: ((IAdjointable)(op)).Adjoint.Apply(QVoid.Instance); break; + case FunctorType.Controlled: ((IControllable)(op)).Controlled.Apply(ctrls); break; + case FunctorType.AdjointControlled: ((IUnitary)(op)).Controlled.Adjoint.Apply(ctrls); break; + } + } + + private static QVoid ExecuteConditionalStatementInternal(QuantumProcessorDispatcher Simulator, + int statement, + ICallable onEqualOp, + ICallable onNonEqualOp, + FunctorType type, + IQArray ctrls) + { + bool run; + + run = Simulator.QuantumProcessor.RunThenClause(statement); + while (run) + { + RunClause(onEqualOp, type, ctrls); + run = Simulator.QuantumProcessor.RepeatThenClause(statement); + } + + run = Simulator.QuantumProcessor.RunElseClause(statement); + while (run) + { + RunClause(onNonEqualOp, type, ctrls); + run = Simulator.QuantumProcessor.RepeatElseClause(statement); + } + + Simulator.QuantumProcessor.EndConditionalStatement(statement); + + return QVoid.Instance; + } + + private static QVoid ExecuteConditionalStatement(QuantumProcessorDispatcher Simulator, + IQArray measurementResults, + IQArray resultsValues, + ICallable onEqualOp, + ICallable onNonEqualOp, + FunctorType type, + IQArray ctrls) + { + int statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResults, resultsValues); + return ExecuteConditionalStatementInternal(Simulator, + statement, + onEqualOp, + onNonEqualOp, + type, + ctrls); + } + + private static QVoid ExecuteConditionalStatement(QuantumProcessorDispatcher Simulator, + Result measurementResult, + Result resultValue, + ICallable onEqualOp, + ICallable onNonEqualOp, + FunctorType type, + IQArray ctrls) + { + int statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResult, resultValue); + return ExecuteConditionalStatementInternal(Simulator, + statement, + onEqualOp, + onNonEqualOp, + type, + ctrls); + } + + public class QuantumProcessorApplyIfElse : Extensions.ApplyIfElseIntrinsic { private QuantumProcessorDispatcher Simulator { get; } @@ -17,10 +99,7 @@ public class QuantumProcessorApplyIfElse : Extensions.ApplyIfElseIntrinsic public override Func<(Result, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); }; } @@ -33,19 +112,13 @@ public class QuantumProcessorApplyIfElseA : Extensions.ApplyIfElseIntrinsicA public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); }; public override Func<(Result, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Adjoint.Apply(QVoid.Instance), - () => onOne.Adjoint.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Adjoint, null); }; } @@ -58,19 +131,13 @@ public class QuantumProcessorApplyIfElseC : Extensions.ApplyIfElseIntrinsicC public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); }; public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Controlled.Apply(ctrls), - () => onOne.Controlled.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Controlled, ctrls); }; } @@ -83,37 +150,25 @@ public class QuantumProcessorApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Apply(QVoid.Instance), - () => onOne.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); }; public override Func<(Result, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Adjoint.Apply(QVoid.Instance), - () => onOne.Adjoint.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Adjoint, null); }; public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Controlled.Apply(ctrls), - () => onOne.Controlled.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Controlled, ctrls); }; public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResult, - () => onZero.Controlled.Adjoint.Apply(ctrls), - () => onOne.Controlled.Adjoint.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.AdjointControlled, ctrls); }; } @@ -128,10 +183,7 @@ public class QuantumProcessorApplyConditionally : Extensions.ApplyConditionallyI public override Func<(IQArray, IQArray, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Apply(QVoid.Instance), - () => onNonEqualOp.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); }; } @@ -144,19 +196,13 @@ public class QuantumProcessorApplyConditionallyA : Extensions.ApplyConditionally public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Apply(QVoid.Instance), - () => onNonEqualOp.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); }; public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Adjoint.Apply(QVoid.Instance), - () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Adjoint, null); }; } @@ -169,19 +215,13 @@ public class QuantumProcessorApplyConditionallyC : Extensions.ApplyConditionally public override Func<(IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Apply(QVoid.Instance), - () => onNonEqualOp.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); }; public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Controlled.Apply(ctrls), - () => onNonEqualOp.Controlled.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Controlled, ctrls); }; } @@ -194,37 +234,25 @@ public class QuantumProcessorApplyConditionallyCA : Extensions.ApplyConditionall public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Apply(QVoid.Instance), - () => onNonEqualOp.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); }; public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Adjoint.Apply(QVoid.Instance), - () => onNonEqualOp.Adjoint.Apply(QVoid.Instance)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Adjoint, null); }; public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Controlled.Apply(ctrls), - () => onNonEqualOp.Controlled.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Controlled, ctrls); }; public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - Simulator.QuantumProcessor.ClassicallyControlled(measurementResults, resultsValues, - () => onEqualOp.Controlled.Adjoint.Apply(ctrls), - () => onNonEqualOp.Controlled.Adjoint.Apply(ctrls)); - return QVoid.Instance; + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.AdjointControlled, ctrls); }; } From c91bad18fd9acfe885d3fa463e8176f4f9a3d400 Mon Sep 17 00:00:00 2001 From: Alexander Vaschillo Date: Thu, 12 Dec 2019 19:50:10 -0800 Subject: [PATCH 11/12] Cleanup --- src/Simulation/Common/QuantumProcessorBase.cs | 183 +++++++++--------- 1 file changed, 92 insertions(+), 91 deletions(-) diff --git a/src/Simulation/Common/QuantumProcessorBase.cs b/src/Simulation/Common/QuantumProcessorBase.cs index 68fec627b64..7a5dc187f95 100644 --- a/src/Simulation/Common/QuantumProcessorBase.cs +++ b/src/Simulation/Common/QuantumProcessorBase.cs @@ -13,271 +13,272 @@ namespace Microsoft.Quantum.Simulation.Common /// public class QuantumProcessorBase : IQuantumProcessor { - public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) + public virtual void X(Qubit qubit) { + throw new NotImplementedException(); } - public virtual void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol) + public virtual void ControlledX(IQArray controls, Qubit qubit) { + throw new NotImplementedException(); } - public virtual int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues) + public virtual void Y(Qubit qubit) { - Debug.Assert(measurementResults.Count == resultsValues.Count); - - int equal = 1; - - for (int i = 0; i < measurementResults.Count; i++) - { - if (measurementResults[i] != resultsValues[i]) - { - equal = 0; - } - } - - return equal; + throw new NotImplementedException(); } - public virtual int StartConditionalStatement(Result measurementResult, Result resultValue) + public virtual void ControlledY(IQArray controls, Qubit qubit) { - - if (measurementResult == resultValue) - { - return 1; - } else - { - return 0; - } + throw new NotImplementedException(); } - public virtual bool RunThenClause(int statement) + public virtual void Z(Qubit qubit) { - return (statement != 0); + throw new NotImplementedException(); } - public virtual bool RepeatThenClause(int statement) + public virtual void ControlledZ(IQArray controls, Qubit qubit) { - return false; + throw new NotImplementedException(); } - public virtual bool RunElseClause(int statement) + public virtual void SWAP(Qubit qubit1, Qubit qubit2) { - return (statement == 0); + throw new NotImplementedException(); } - public virtual bool RepeatElseClause(int statement) + public virtual void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2) { - return false; + throw new NotImplementedException(); } - public virtual void EndConditionalStatement(int id) + public virtual void H(Qubit qubit) { - + throw new NotImplementedException(); } - public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) + public virtual void ControlledH(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits) + public virtual void S(Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledH(IQArray controls, Qubit qubit) + public virtual void ControlledS(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit) + public virtual void SAdjoint(Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledR1(IQArray controls, double theta, Qubit qubit) + public virtual void ControlledSAdjoint(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit) + public virtual void T(Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit) + public virtual void ControlledT(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledS(IQArray controls, Qubit qubit) + public virtual void TAdjoint(Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledSAdjoint(IQArray controls, Qubit qubit) + public virtual void ControlledTAdjoint(IQArray controls, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledSWAP(IQArray controls, Qubit qubit1, Qubit qubit2) + public virtual void R(Pauli axis, double theta, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledT(IQArray controls, Qubit qubit) + public virtual void ControlledR(IQArray controls, Pauli axis, double theta, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledTAdjoint(IQArray controls, Qubit qubit) + public virtual void RFrac(Pauli axis, long numerator, long power, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledX(IQArray controls, Qubit qubit) + public virtual void ControlledRFrac(IQArray controls, Pauli axis, long numerator, long power, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledY(IQArray controls, Qubit qubit) + public virtual void R1(double theta, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ControlledZ(IQArray controls, Qubit qubit) + public virtual void ControlledR1(IQArray controls, double theta, Qubit qubit) { throw new NotImplementedException(); } - public virtual void Exp(IQArray paulis, double theta, IQArray qubits) + public virtual void R1Frac(long numerator, long power, Qubit qubit) { throw new NotImplementedException(); } - public virtual void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits) + public virtual void ControlledR1Frac(IQArray controls, long numerator, long power, Qubit qubit) { throw new NotImplementedException(); } - public virtual void H(Qubit qubit) + public virtual void Exp(IQArray paulis, double theta, IQArray qubits) { throw new NotImplementedException(); } - public virtual Result M(Qubit qubit) + public virtual void ControlledExp(IQArray controls, IQArray paulis, double theta, IQArray qubits) { throw new NotImplementedException(); } - public virtual Result Measure(IQArray bases, IQArray qubits) + public virtual void ExpFrac(IQArray paulis, long numerator, long power, IQArray qubits) { throw new NotImplementedException(); } - public virtual void OnAllocateQubits(IQArray qubits) + public virtual void ControlledExpFrac(IQArray controls, IQArray paulis, long numerator, long power, IQArray qubits) { + throw new NotImplementedException(); } - public virtual void OnBorrowQubits(IQArray qubits) + public virtual Result M(Qubit qubit) { + throw new NotImplementedException(); } - public virtual void OnDumpMachine(T location) + public virtual Result Measure(IQArray bases, IQArray qubits) { + throw new NotImplementedException(); } - public virtual void OnDumpRegister(T location, IQArray qubits) + public virtual void Reset(Qubit qubit) { + throw new NotImplementedException(); } - public virtual void OnMessage(string msg) + public virtual int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues) { + Debug.Assert(measurementResults.Count == resultsValues.Count); + + int equal = 1; + + for (int i = 0; i < measurementResults.Count; i++) + { + if (measurementResults[i] != resultsValues[i]) + { + equal = 0; + } + } + + return equal; } - public virtual void OnOperationEnd(ICallable operation, IApplyData arguments) + public virtual int StartConditionalStatement(Result measurementResult, Result resultValue) { + + if (measurementResult == resultValue) + { + return 1; + } else + { + return 0; + } } - public virtual void OnOperationStart(ICallable operation, IApplyData arguments) + public virtual bool RunThenClause(int statement) { + return (statement != 0); } - public virtual void OnFail(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo) + public virtual bool RepeatThenClause(int statement) { + return false; } - public virtual void OnReleaseQubits(IQArray qubits) + public virtual bool RunElseClause(int statement) { + return (statement == 0); } - public virtual void OnReturnQubits(IQArray qubits) + public virtual bool RepeatElseClause(int statement) { + return false; } - public virtual void R(Pauli axis, double theta, Qubit qubit) + public virtual void EndConditionalStatement(int id) { - throw new NotImplementedException(); + } - public virtual void R1(double theta, Qubit qubit) + public virtual void Assert(IQArray bases, IQArray qubits, Result result, string msg) { - throw new NotImplementedException(); } - public virtual void R1Frac(long numerator, long power, Qubit qubit) + public virtual void AssertProb(IQArray bases, IQArray qubits, double probabilityOfZero, string msg, double tol) { - throw new NotImplementedException(); } - public virtual void Reset(Qubit qubit) + public virtual void OnOperationStart(ICallable operation, IApplyData arguments) { - throw new NotImplementedException(); } - public virtual void RFrac(Pauli axis, long numerator, long power, Qubit qubit) + public virtual void OnOperationEnd(ICallable operation, IApplyData arguments) { - throw new NotImplementedException(); } - public virtual void S(Qubit qubit) + public virtual void OnFail(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo) { - throw new NotImplementedException(); } - public virtual void SAdjoint(Qubit qubit) + public virtual void OnAllocateQubits(IQArray qubits) { - throw new NotImplementedException(); } - public virtual void SWAP(Qubit qubit1, Qubit qubit2) + public virtual void OnReleaseQubits(IQArray qubits) { - throw new NotImplementedException(); } - public virtual void T(Qubit qubit) + public virtual void OnBorrowQubits(IQArray qubits) { - throw new NotImplementedException(); } - public virtual void TAdjoint(Qubit qubit) + public virtual void OnReturnQubits(IQArray qubits) { - throw new NotImplementedException(); } - public virtual void X(Qubit qubit) + public virtual void OnDumpMachine(T location) { - throw new NotImplementedException(); } - public virtual void Y(Qubit qubit) + public virtual void OnDumpRegister(T location, IQArray qubits) { - throw new NotImplementedException(); } - public virtual void Z(Qubit qubit) + public virtual void OnMessage(string msg) { - throw new NotImplementedException(); } + } } From 8fa0d64c9bfc59c04c96e73561b01edc49162717 Mon Sep 17 00:00:00 2001 From: alexva Date: Fri, 13 Dec 2019 13:31:14 -0800 Subject: [PATCH 12/12] Small improvements --- src/Simulation/Common/IQuantumProcessor.cs | 24 +++---- src/Simulation/Common/QuantumProcessorBase.cs | 17 ++--- .../QuantumProcessor/ClassicalControl.cs | 65 +++++++++---------- 3 files changed, 50 insertions(+), 56 deletions(-) diff --git a/src/Simulation/Common/IQuantumProcessor.cs b/src/Simulation/Common/IQuantumProcessor.cs index 3e8ca1d0534..565b44d0356 100644 --- a/src/Simulation/Common/IQuantumProcessor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -436,7 +436,7 @@ public interface IQuantumProcessor /// /// A typical implementation will compare all to and return the result of this comparison. /// - int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues); + long StartConditionalStatement(IQArray measurementResults, IQArray resultsValues); /// /// Intended for a limited support of branching upon measurement results on a target machine level. @@ -444,11 +444,11 @@ public interface IQuantumProcessor /// /// The actual result of the measurement of a qubit upon which branching is to be performed. /// The expected value of result of the measurement of this qubit. - /// A value representing this conditional statement and encoding the result of condition. + /// A value representing this conditional statement and encoding the result of the condition. It will be passed through to the other branching related APIs such as RunThenClause. /// /// A typical implementation will compare to and return the result of this comparison. /// - int StartConditionalStatement(Result measurementResult, Result resultValue); + long StartConditionalStatement(Result measurementResult, Result resultValue); /// /// Intended for a limited support of branching upon measurement results on a target machine level. @@ -459,50 +459,50 @@ public interface IQuantumProcessor /// /// A typical implementation will use to return whether condition was evaluated to true. /// - bool RunThenClause(int statement); + bool RunThenClause(long statement); /// /// Intended for a limited support of branching upon measurement results on a target machine level. /// Called when the "then" statement of a conditional statement has finished executing. /// - /// A value representing this conditional statement and encoding the result of condition. + /// A value representing this conditional statement and encoding the result of the condition. This is the value returned from the StartConditionalStatement. /// If true is returned, the "then" statement will be executed again (without calling RunThenClause), folowed by another call to RepeatThenClause. /// /// A typical implementation will return false. /// - bool RepeatThenClause(int statement); + bool RepeatThenClause(long statement); /// /// Intended for a limited support of branching upon measurement results on a target machine level. /// Called when the "else" statement of a conditional statement is about to be executed. /// - /// A value representing this conditional statement and encoding the result of condition. + /// A value representing this conditional statement and encoding the result of the condition. This is the value returned from the StartConditionalStatement. /// If true is returned, the "else" statement will be executed, otherwise it will be skipped and RepeatElseClause will not be called. /// /// A typical implementation will use to return whether condition was evaluated to false. /// - bool RunElseClause(int statement); + bool RunElseClause(long statement); /// /// Intended for a limited support of branching upon measurement results on a target machine level. /// Called when the "else" statement of a conditional statement has finished executing. /// - /// A value representing this conditional statement and encoding the result of condition. + /// A value representing this conditional statement and encoding the result of the condition. This is the value returned from the StartConditionalStatement. /// If true is returned, the "else" statement will be executed again (without calling RunElseClause), folowed by another call to RepeatElseClause. /// /// A typical implementation will return false. /// - bool RepeatElseClause(int statement); + bool RepeatElseClause(long statement); /// /// Intended for a limited support of branching upon measurement results on a target machine level. /// Called when a conditional statement on measurement results has finished executing. /// - /// A value representing this conditional statement and encoding the result of condition. + /// A value representing this conditional statement and encoding the result of the condition. This is the value returned from the StartConditionalStatement. /// /// A typical implementation will clean up any data structures associated with statement. /// - void EndConditionalStatement(int statement); + void EndConditionalStatement(long statement); /// /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. diff --git a/src/Simulation/Common/QuantumProcessorBase.cs b/src/Simulation/Common/QuantumProcessorBase.cs index 7a5dc187f95..00ca208c33c 100644 --- a/src/Simulation/Common/QuantumProcessorBase.cs +++ b/src/Simulation/Common/QuantumProcessorBase.cs @@ -178,7 +178,7 @@ public virtual void Reset(Qubit qubit) throw new NotImplementedException(); } - public virtual int StartConditionalStatement(IQArray measurementResults, IQArray resultsValues) + public virtual long StartConditionalStatement(IQArray measurementResults, IQArray resultsValues) { Debug.Assert(measurementResults.Count == resultsValues.Count); @@ -195,39 +195,40 @@ public virtual int StartConditionalStatement(IQArray measurementResults, return equal; } - public virtual int StartConditionalStatement(Result measurementResult, Result resultValue) + public virtual long StartConditionalStatement(Result measurementResult, Result resultValue) { if (measurementResult == resultValue) { return 1; - } else + } + else { return 0; } } - public virtual bool RunThenClause(int statement) + public virtual bool RunThenClause(long statement) { return (statement != 0); } - public virtual bool RepeatThenClause(int statement) + public virtual bool RepeatThenClause(long statement) { return false; } - public virtual bool RunElseClause(int statement) + public virtual bool RunElseClause(long statement) { return (statement == 0); } - public virtual bool RepeatElseClause(int statement) + public virtual bool RepeatElseClause(long statement) { return false; } - public virtual void EndConditionalStatement(int id) + public virtual void EndConditionalStatement(long id) { } diff --git a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs index 7113456f977..ded65c58b09 100644 --- a/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs +++ b/src/Simulation/Simulators/QuantumProcessor/ClassicalControl.cs @@ -8,30 +8,23 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor { public partial class QuantumProcessorDispatcher { - private enum FunctorType - { - Body, - Adjoint, - Controlled, - AdjointControlled, - } - private static void RunClause(ICallable op, FunctorType type, IQArray ctrls) + private static void RunClause(ICallable op, OperationFunctor type, IQArray ctrls) { switch (type) { - case FunctorType.Body: op.Apply(QVoid.Instance); break; - case FunctorType.Adjoint: ((IAdjointable)(op)).Adjoint.Apply(QVoid.Instance); break; - case FunctorType.Controlled: ((IControllable)(op)).Controlled.Apply(ctrls); break; - case FunctorType.AdjointControlled: ((IUnitary)(op)).Controlled.Adjoint.Apply(ctrls); break; + case OperationFunctor.Body: op.Apply(QVoid.Instance); break; + case OperationFunctor.Adjoint: ((IAdjointable)(op)).Adjoint.Apply(QVoid.Instance); break; + case OperationFunctor.Controlled: ((IControllable)(op)).Controlled.Apply(ctrls); break; + case OperationFunctor.ControlledAdjoint: ((IUnitary)(op)).Controlled.Adjoint.Apply(ctrls); break; } } private static QVoid ExecuteConditionalStatementInternal(QuantumProcessorDispatcher Simulator, - int statement, + long statement, ICallable onEqualOp, ICallable onNonEqualOp, - FunctorType type, + OperationFunctor type, IQArray ctrls) { bool run; @@ -60,10 +53,10 @@ private static QVoid ExecuteConditionalStatement(QuantumProcessorDispatcher Simu IQArray resultsValues, ICallable onEqualOp, ICallable onNonEqualOp, - FunctorType type, + OperationFunctor type, IQArray ctrls) { - int statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResults, resultsValues); + long statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResults, resultsValues); return ExecuteConditionalStatementInternal(Simulator, statement, onEqualOp, @@ -77,10 +70,10 @@ private static QVoid ExecuteConditionalStatement(QuantumProcessorDispatcher Simu Result resultValue, ICallable onEqualOp, ICallable onNonEqualOp, - FunctorType type, + OperationFunctor type, IQArray ctrls) { - int statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResult, resultValue); + long statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResult, resultValue); return ExecuteConditionalStatementInternal(Simulator, statement, onEqualOp, @@ -99,7 +92,7 @@ public class QuantumProcessorApplyIfElse : Extensions.ApplyIfElseIntrinsic public override Func<(Result, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Body, null); }; } @@ -112,13 +105,13 @@ public class QuantumProcessorApplyIfElseA : Extensions.ApplyIfElseIntrinsicA public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Body, null); }; public override Func<(Result, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Adjoint, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Adjoint, null); }; } @@ -131,13 +124,13 @@ public class QuantumProcessorApplyIfElseC : Extensions.ApplyIfElseIntrinsicC public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Body, null); }; public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Controlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Controlled, ctrls); }; } @@ -150,25 +143,25 @@ public class QuantumProcessorApplyIfElseCA : Extensions.ApplyIfElseIntrinsicCA public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Body, null); }; public override Func<(Result, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResult, onZero, onOne) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Adjoint, null); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Adjoint, null); }; public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.Controlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.Controlled, ctrls); }; public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResult, onZero, onOne)) = q; - return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, FunctorType.AdjointControlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResult, Result.Zero, onZero, onOne, OperationFunctor.ControlledAdjoint, ctrls); }; } @@ -183,7 +176,7 @@ public class QuantumProcessorApplyConditionally : Extensions.ApplyConditionallyI public override Func<(IQArray, IQArray, ICallable, ICallable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); }; } @@ -196,13 +189,13 @@ public class QuantumProcessorApplyConditionallyA : Extensions.ApplyConditionally public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); }; public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Adjoint, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Adjoint, null); }; } @@ -215,13 +208,13 @@ public class QuantumProcessorApplyConditionallyC : Extensions.ApplyConditionally public override Func<(IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); }; public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Controlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Controlled, ctrls); }; } @@ -234,25 +227,25 @@ public class QuantumProcessorApplyConditionallyCA : Extensions.ApplyConditionall public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Body, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); }; public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> AdjointBody => (q) => { var (measurementResults, resultsValues, onEqualOp, onNonEqualOp) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Adjoint, null); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Adjoint, null); }; public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.Controlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.Controlled, ctrls); }; public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { var (ctrls, (measurementResults, resultsValues, onEqualOp, onNonEqualOp)) = q; - return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, FunctorType.AdjointControlled, ctrls); + return ExecuteConditionalStatement(Simulator, measurementResults, resultsValues, onEqualOp, onNonEqualOp, OperationFunctor.ControlledAdjoint, ctrls); }; }