Loading examples/qcor_demos/ibm_qasm3_demo_082021/conditional_feedback/measure_conditional.qasm 0 → 100644 +80 −0 Original line number Diff line number Diff line OPENQASM 3; include "qelib1.inc"; // NISQ-mode lowering to conditional (If) statements // Compile targeting nisq runtime and a capable QPU: // (1) Qpp simulator (default): // qcor -qrt nisq -shots 1024 measure_conditional.qasm -print-final-submission // (2) Aer simulator (inspect the QObj to see the use of "conditional" to control quantum instructions) // qcor -qrt nisq -qpu aer -shots 1024 measure_conditional.qasm -print-final-submission // (3) Honeywell: see the OpenQASM2 with if statements. // qcor -qrt nisq -qpu honeywell:HQS-LT-S1-APIVAL -shots 1024 measure_conditional.qasm -print-final-submission // Expected to get 4 bits (iteratively) of 1011 (or 1101 LSB) = 11(decimal): // phi_est = 11/16 (denom = 16 since we have 4 bits) // => phi = 2pi * 11/16 = 11pi/8 = 2pi - 5pi/8 // i.e. we estimate the -5*pi/8 angle... qubit q[2]; const bits_precision = 4; bit c[bits_precision]; // Prepare the eigen-state: |1> x q[1]; // First bit h q[0]; // Controlled rotation: CU^k for i in [0:8] { cphase(-5*pi/8) q[0], q[1]; } h q[0]; // Measure and reset measure q[0] -> c[0]; reset q[0]; // Second bit h q[0]; for i in [0:4] { cphase(-5*pi/8) q[0], q[1]; } // Conditional rotation if (c[0] == 1) { rz(-pi/2) q[0]; } h q[0]; // Measure and reset measure q[0] -> c[1]; reset q[0]; // Third bit h q[0]; for i in [0:2] { cphase(-5*pi/8) q[0], q[1]; } // Conditional rotation if (c[0] == 1) { rz(-pi/4) q[0]; } if (c[1] == 1) { rz(-pi/2) q[0]; } h q[0]; // Measure and reset measure q[0] -> c[2]; reset q[0]; // Fourth bit h q[0]; cphase(-5*pi/8) q[0], q[1]; // Conditional rotation if (c[0] == 1) { rz(-pi/8) q[0]; } if (c[1] == 1) { rz(-pi/4) q[0]; } if (c[2] == 1) { rz(-pi/2) q[0]; } h q[0]; measure q[0] -> c[3]; No newline at end of file examples/qcor_demos/ibm_qasm3_demo_082021/integration/1_qcor_call_qsharp_qpe/qft.qs 0 → 100644 +33 −0 Original line number Diff line number Diff line namespace QCOR { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Canon; operation SWAP(q1 : Qubit, q2: Qubit) : Unit is Adj { CNOT(q1, q2); CNOT(q2, q1); CNOT(q1, q2); } operation IQFT(qq: Qubit[]): Unit { Message("Hello from Q# IQFT"); for i in 0 .. Length(qq)/2 - 1 { SWAP(qq[i], qq[Length(qq)-i-1]); } for i in 0 .. Length(qq) - 2 { H(qq[i]); let j = i + 1; mutable y = i; repeat { let theta = -3.14159 / IntAsDouble(1 <<< (j-y)); // Controlled R1 == CPhase Controlled R1([qq[j]], (theta, qq[y])); set y = y - 1; } until (y < 0); } H(qq[Length(qq) -1]); } } No newline at end of file examples/qcor_demos/ibm_qasm3_demo_082021/integration/1_qcor_call_qsharp_qpe/qpe.cpp 0 → 100644 +45 −0 Original line number Diff line number Diff line #include "qir_nisq_kernel_utils.hpp" // Compile: // qcor qft.qs qpe.cpp -shots 1024 -print-final-submission qcor_import_qsharp_kernel(QCOR__IQFT); // Typedef for the Oracle Kernel Function using QPEOracleSignature = KernelSignature<qubit>; __qpu__ void qpe(qreg q, QPEOracleSignature oracle) { // Extract the counting qubits and the state qubit auto counting_qubits = q.extract_range({0,3}); auto state_qubit = q[3]; // Put it in |1> eigenstate X(state_qubit); // Create uniform superposition on all 3 qubits H(counting_qubits); // run ctr-oracle operations for (auto i : range(counting_qubits.size())) { const int nbCalls = 1 << i; for (auto j : range(nbCalls)) { oracle.ctrl(counting_qubits[i], state_qubit); } } // Run Inverse QFT on counting qubits // Using the Q# Kernel (wrapped as a QCOR kernel) QCOR__IQFT(counting_qubits); // Measure the counting qubits Measure(counting_qubits); } // Oracle to consider __qpu__ void oracle(qubit q) { T(q); } int main(int argc, char **argv) { auto q = qalloc(4); qpe::print_kernel(q, oracle); // Run qpe(q, oracle); q.print(); } examples/qcor_demos/ibm_qasm3_demo_082021/integration/2_qcor_call_qasm3_qpe/iqft.qasm 0 → 100644 +25 −0 Original line number Diff line number Diff line OPENQASM 3; // QCOR can scan for this and make // sure MLIRGen does not add main() // This is useful for QASM3 files that are // purely library functions #pragma no_entrypoint; // Inverse QFT subroutine on n_counting qubits def inverse_qft(int[64]:nc) qubit[nc]:qq { for i in [0:nc/2] { swap qq[i], qq[nc-i-1]; } for i in [0:nc-1] { h qq[i]; int j = i + 1; int y = i; while (y >= 0) { double theta = -pi / (2^(j-y)); cphase(theta) qq[j], qq[y]; y -= 1; } } h qq[nc-1]; } No newline at end of file examples/qcor_demos/ibm_qasm3_demo_082021/integration/2_qcor_call_qasm3_qpe/qpe.cpp 0 → 100644 +46 −0 Original line number Diff line number Diff line #include "qir_nisq_kernel_utils.hpp" // Compile: // qcor qft.qasm qpe.cpp -shots 1024 using QPEOracleSignature = KernelSignature<qubit>; // External QASM3 function with signature void(qreg, int) // All imported kernels assumed to take qreg as first arg qcor_import_qasm3_kernel(inverse_qft, int); __qpu__ void qpe(qreg q, QPEOracleSignature oracle) { // Extract the counting qubits and the state qubit auto counting_qubits = q.extract_range({0,3}); auto state_qubit = q[3]; // Put it in |1> eigenstate X(state_qubit); // Create uniform superposition on all 3 qubits H(counting_qubits); // run ctr-oracle operations for (auto i : range(counting_qubits.size())) { const int nbCalls = 1 << i; for (auto j : range(nbCalls)) { oracle.ctrl(counting_qubits[i], state_qubit); } } // Run Inverse QFT on counting qubits // Using the Q# Kernel (wrapped as a QCOR kernel) // Signature is void(qreg, int) as per above import stmt inverse_qft(counting_qubits, counting_qubits.size()); // Measure the counting qubits Measure(counting_qubits); } // Oracle to consider __qpu__ void oracle(qubit q) { T(q); } int main(int argc, char **argv) { auto q = qalloc(4); qpe::print_kernel(q, oracle); // Run qpe(q, oracle); q.print(); } Loading
examples/qcor_demos/ibm_qasm3_demo_082021/conditional_feedback/measure_conditional.qasm 0 → 100644 +80 −0 Original line number Diff line number Diff line OPENQASM 3; include "qelib1.inc"; // NISQ-mode lowering to conditional (If) statements // Compile targeting nisq runtime and a capable QPU: // (1) Qpp simulator (default): // qcor -qrt nisq -shots 1024 measure_conditional.qasm -print-final-submission // (2) Aer simulator (inspect the QObj to see the use of "conditional" to control quantum instructions) // qcor -qrt nisq -qpu aer -shots 1024 measure_conditional.qasm -print-final-submission // (3) Honeywell: see the OpenQASM2 with if statements. // qcor -qrt nisq -qpu honeywell:HQS-LT-S1-APIVAL -shots 1024 measure_conditional.qasm -print-final-submission // Expected to get 4 bits (iteratively) of 1011 (or 1101 LSB) = 11(decimal): // phi_est = 11/16 (denom = 16 since we have 4 bits) // => phi = 2pi * 11/16 = 11pi/8 = 2pi - 5pi/8 // i.e. we estimate the -5*pi/8 angle... qubit q[2]; const bits_precision = 4; bit c[bits_precision]; // Prepare the eigen-state: |1> x q[1]; // First bit h q[0]; // Controlled rotation: CU^k for i in [0:8] { cphase(-5*pi/8) q[0], q[1]; } h q[0]; // Measure and reset measure q[0] -> c[0]; reset q[0]; // Second bit h q[0]; for i in [0:4] { cphase(-5*pi/8) q[0], q[1]; } // Conditional rotation if (c[0] == 1) { rz(-pi/2) q[0]; } h q[0]; // Measure and reset measure q[0] -> c[1]; reset q[0]; // Third bit h q[0]; for i in [0:2] { cphase(-5*pi/8) q[0], q[1]; } // Conditional rotation if (c[0] == 1) { rz(-pi/4) q[0]; } if (c[1] == 1) { rz(-pi/2) q[0]; } h q[0]; // Measure and reset measure q[0] -> c[2]; reset q[0]; // Fourth bit h q[0]; cphase(-5*pi/8) q[0], q[1]; // Conditional rotation if (c[0] == 1) { rz(-pi/8) q[0]; } if (c[1] == 1) { rz(-pi/4) q[0]; } if (c[2] == 1) { rz(-pi/2) q[0]; } h q[0]; measure q[0] -> c[3]; No newline at end of file
examples/qcor_demos/ibm_qasm3_demo_082021/integration/1_qcor_call_qsharp_qpe/qft.qs 0 → 100644 +33 −0 Original line number Diff line number Diff line namespace QCOR { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Canon; operation SWAP(q1 : Qubit, q2: Qubit) : Unit is Adj { CNOT(q1, q2); CNOT(q2, q1); CNOT(q1, q2); } operation IQFT(qq: Qubit[]): Unit { Message("Hello from Q# IQFT"); for i in 0 .. Length(qq)/2 - 1 { SWAP(qq[i], qq[Length(qq)-i-1]); } for i in 0 .. Length(qq) - 2 { H(qq[i]); let j = i + 1; mutable y = i; repeat { let theta = -3.14159 / IntAsDouble(1 <<< (j-y)); // Controlled R1 == CPhase Controlled R1([qq[j]], (theta, qq[y])); set y = y - 1; } until (y < 0); } H(qq[Length(qq) -1]); } } No newline at end of file
examples/qcor_demos/ibm_qasm3_demo_082021/integration/1_qcor_call_qsharp_qpe/qpe.cpp 0 → 100644 +45 −0 Original line number Diff line number Diff line #include "qir_nisq_kernel_utils.hpp" // Compile: // qcor qft.qs qpe.cpp -shots 1024 -print-final-submission qcor_import_qsharp_kernel(QCOR__IQFT); // Typedef for the Oracle Kernel Function using QPEOracleSignature = KernelSignature<qubit>; __qpu__ void qpe(qreg q, QPEOracleSignature oracle) { // Extract the counting qubits and the state qubit auto counting_qubits = q.extract_range({0,3}); auto state_qubit = q[3]; // Put it in |1> eigenstate X(state_qubit); // Create uniform superposition on all 3 qubits H(counting_qubits); // run ctr-oracle operations for (auto i : range(counting_qubits.size())) { const int nbCalls = 1 << i; for (auto j : range(nbCalls)) { oracle.ctrl(counting_qubits[i], state_qubit); } } // Run Inverse QFT on counting qubits // Using the Q# Kernel (wrapped as a QCOR kernel) QCOR__IQFT(counting_qubits); // Measure the counting qubits Measure(counting_qubits); } // Oracle to consider __qpu__ void oracle(qubit q) { T(q); } int main(int argc, char **argv) { auto q = qalloc(4); qpe::print_kernel(q, oracle); // Run qpe(q, oracle); q.print(); }
examples/qcor_demos/ibm_qasm3_demo_082021/integration/2_qcor_call_qasm3_qpe/iqft.qasm 0 → 100644 +25 −0 Original line number Diff line number Diff line OPENQASM 3; // QCOR can scan for this and make // sure MLIRGen does not add main() // This is useful for QASM3 files that are // purely library functions #pragma no_entrypoint; // Inverse QFT subroutine on n_counting qubits def inverse_qft(int[64]:nc) qubit[nc]:qq { for i in [0:nc/2] { swap qq[i], qq[nc-i-1]; } for i in [0:nc-1] { h qq[i]; int j = i + 1; int y = i; while (y >= 0) { double theta = -pi / (2^(j-y)); cphase(theta) qq[j], qq[y]; y -= 1; } } h qq[nc-1]; } No newline at end of file
examples/qcor_demos/ibm_qasm3_demo_082021/integration/2_qcor_call_qasm3_qpe/qpe.cpp 0 → 100644 +46 −0 Original line number Diff line number Diff line #include "qir_nisq_kernel_utils.hpp" // Compile: // qcor qft.qasm qpe.cpp -shots 1024 using QPEOracleSignature = KernelSignature<qubit>; // External QASM3 function with signature void(qreg, int) // All imported kernels assumed to take qreg as first arg qcor_import_qasm3_kernel(inverse_qft, int); __qpu__ void qpe(qreg q, QPEOracleSignature oracle) { // Extract the counting qubits and the state qubit auto counting_qubits = q.extract_range({0,3}); auto state_qubit = q[3]; // Put it in |1> eigenstate X(state_qubit); // Create uniform superposition on all 3 qubits H(counting_qubits); // run ctr-oracle operations for (auto i : range(counting_qubits.size())) { const int nbCalls = 1 << i; for (auto j : range(nbCalls)) { oracle.ctrl(counting_qubits[i], state_qubit); } } // Run Inverse QFT on counting qubits // Using the Q# Kernel (wrapped as a QCOR kernel) // Signature is void(qreg, int) as per above import stmt inverse_qft(counting_qubits, counting_qubits.size()); // Measure the counting qubits Measure(counting_qubits); } // Oracle to consider __qpu__ void oracle(qubit q) { T(q); } int main(int argc, char **argv) { auto q = qalloc(4); qpe::print_kernel(q, oracle); // Run qpe(q, oracle); q.print(); }