Unverified Commit ddf60396 authored by Mccaskey, Alex's avatar Mccaskey, Alex Committed by GitHub
Browse files

Merge pull request #185 from tnguyen-ornl/tnguyen/qasm3-as-qsharp-callables

Using QASM3 subroutines as Qsharp callables
parents 6131cb62 94183cc4
Loading
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line

// Driver to tie them all together:
// - Declare the exported QASM3 callable 
// - Use that as input to the Q# operation

// Compile with:
// qcor -qrt ftqc op_takes_callable.qs kernel.qasm driver.cpp -v

// Note: this driver can be part of QASM3 as well, but
// we don't have the concept of Callable type in QASM3 yet,
// hence, we cannot declare the Q# kernel taking Callable argumements as extern
// in QASM3 yet.
#include "qir-types.hpp"

// QASM3 function wrapping the quantum sub-routine as a QIR Callable
extern "C" ::Callable* qasm_x__callable(); 
// Q# functions:
// Apply an op to all qubits using the ApplyToEachCA util of Q#
extern "C" void QCOR__ApplyKernelToEachQubit__body(::Callable *);
// Apply Controlled version of a Callable (X gate in QASM3)
// This will just be a Bell experiment.
extern "C" void QCOR__ApplyControlledKernel__body(::Callable *);
int main() {
  // Get the callable (QASM3)
  auto qasm3_callable = qasm_x__callable();
  // Pass it to Q#
  // std::cout << "Apply the functor to each qubit:\n";
  // QCOR__ApplyKernelToEachQubit__body(qasm3_callable);

  // Run Bell experiment:
  constexpr int COUNT = 100;
  std::cout << "Apply controlled functor(Bell test):\n";
  for (int i = 0; i < COUNT; ++i) {
    std::cout << "Run " << i + 1 << ":\n";
    QCOR__ApplyControlledKernel__body(qasm3_callable);
  }
  return 0;
}
 No newline at end of file
+10 −0
Original line number Diff line number Diff line
#pragma no_entrypoint;

OPENQASM 3;
include "stdgates.inc";

#pragma { export; }
def qasm_x qubit:qb {
  print("Hello from QASM3!");
  x qb;
}
+42 −0
Original line number Diff line number Diff line
namespace QCOR 
{
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Canon;

operation ApplyKernelToEachQubit(singleElementOperation : (Qubit => Unit is Adj + Ctl)): Unit {
  use q = Qubit[5];
  ApplyToEachCA(singleElementOperation, q);
  for idx in 0..4 {
    let res = M(q[idx]);    
    if res == One {
      Message("Get one");
    } else {
      Message("Get zero");
    }
  }
}

operation ApplyControlledKernel(singleElementOperation : ((Qubit) => Unit is Adj + Ctl)): Unit {
  use q = Qubit[2];
  
  H(q[0]);
  // Apply controlled
  Controlled singleElementOperation([q[0]], (q[1])); 
  let res0 = M(q[0]);    
  if res0 == One {
    Message("Meas Q0 -> one");
    X(q[0]);
  } else {
    Message("Meas Q0 -> zero");
  }

  let res1 = M(q[1]);    
  if res1 == One {
    Message("Meas Q1 -> one");
    X(q[1]);
  } else {
    Message("Meas Q0 -> zero");
  }
}
}
 No newline at end of file
+33 −0
Original line number Diff line number Diff line

// Demonstrate integration b/w QASM3 kernels with Q# Library code:
// in this case EstimateRealOverlapBetweenStates from the Standard Library (Hadamard test)
// https://github.com/microsoft/QuantumLibraries/blob/main/Standard/src/Characterization/Distinguishability.qs
// Driver to tie them all together:
// - Declare the exported QASM3 callable 
// - Use that as input to the Q# operation

// Compile with:
// qcor -qrt ftqc overlap_calc.qs kernel.qasm driver.cpp

// Note: this driver can be part of QASM3 as well, but
// we don't have the concept of Callable type in QASM3 yet,
// hence, we cannot declare the Q# kernel taking Callable argumements as extern
// in QASM3 yet.
#include "qir-types.hpp"

// QASM3 function wrapping the quantum sub-routine as a QIR Callable
extern "C" ::Callable* qasm_x__callable(); 
extern "C" ::Callable* qasm_h__callable(); 
// Q# functions:
// Compute the overlap b/w states prepared by two ansatz kernels (defined in QASM3)
extern "C" double QCOR__ComputeOverlapBetweenState__body(::Callable *, ::Callable *, int64_t /*n iters*/);

int main() {
  const double overlapped = QCOR__ComputeOverlapBetweenState__body(
      qasm_x__callable(), qasm_h__callable(), 10000);
  // Print out the results:
  // Expected: 1/sqrt(2) b/w |1> and |+> state.
  std::cout << "Overlap = " << overlapped
            << " vs. expected = " << 1.0 / std::sqrt(2.0) << "\n";
  return 0;
}
 No newline at end of file
+14 −0
Original line number Diff line number Diff line
#pragma no_entrypoint;

OPENQASM 3;
include "stdgates.inc";

#pragma { export; }
def qasm_x qubit:qb {
  x qb;
}

#pragma { export; }
def qasm_h qubit:qb {
  h qb;
}
 No newline at end of file
Loading