Commit cdd1509f authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

a bit of cleanup, adding using qcor namespace to preamble

parent 23db9032
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
#include <qalloc>

__qpu__ void add_3_5(qreg a, qreg b, qreg c) {
  using qcor::openqasm;
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ __qpu__ void ccnot(qreg q) {
  using qcor::unitary;
  
  // Create the unitary matrix
  qcor::UnitaryMatrix ccnot = qcor::UnitaryMatrix::Identity(8, 8);
  UnitaryMatrix ccnot = UnitaryMatrix::Identity(8, 8);
  ccnot(6, 6) = 0.0;
  ccnot(7, 7) = 0.0;
  ccnot(6, 7) = 1.0;
+5 −212
Original line number Diff line number Diff line
@@ -66,7 +66,11 @@ public:
      if (type == "class xacc::internal_compiler::qreg") {
        bufferNames.push_back(ident->getName().str());
        type = "qreg";
      } else if (type == "qcor::qreg") {
        bufferNames.push_back(ident->getName().str());
        type = "qreg";
      }

      program_arg_types.push_back(type);
      program_parameters.push_back(var);
    }
@@ -260,7 +264,7 @@ public:

  void AddToPredefines(llvm::raw_string_ostream &OS) override {
    OS << "#include \"qcor.hpp\"\n";

    OS << "using namespace qcor;\n";
    OS << "using namespace xacc::internal_compiler;\n";
  }
};
@@ -313,217 +317,6 @@ public:
  }
};

//// =================== COMMON CODE ==============/////
// Base class of all kernels:
// This will handle Adjoint() and Control() in an AUTOMATIC way,
// i.e. not taking into account if it is self-adjoint.
// Technically, we can define sub-classes for those special cases
// and then allow users to annotate kernels as self-adjoint for instance.
// class KernelBase {
// public:
//   KernelBase(xacc::internal_compiler::qreg q,
//              std::shared_ptr<xacc::CompositeInstruction> bodyComposite)
//       : m_qreg(q), m_usedAsCallable(true), m_body(bodyComposite) {}
//   // Adjoint
//   virtual KernelBase adjoint() {
//     // Copy this
//     KernelBase adjointKernel(this, "KernelName_ADJ");
//     // Reverse all instructions in m_body and replace instructions
//     // with their adjoint:
//     // T -> Tdag; Rx(theta) -> Rx(-theta), etc.
//     auto instructions = adjointKernel.m_body->getInstructions();
//     // Assert that we don't have measurement
//     if (!std::all_of(
//             instructions.cbegin(), instructions.cend(),
//             [](const auto &inst) { return inst->name() != "Measure"; })) {
//       xacc::error(
//           "Unable to create Adjoint for kernels that have Measure
//           operations.");
//     }
//     std::reverse(instructions.begin(), instructions.end());
//     for (const auto &inst : instructions) {
//       // Parametric gates:
//       if (inst->name() == "Rx" || inst->name() == "Ry" ||
//           inst->name() == "Rz" || inst->name() == "CPHASE") {
//         inst->setParameter(0, -inst->getParameter(0).as<double>());
//       }
//       // TODO: Handles T and S gates, etc... => T -> Tdg
//     }
//     adjointKernel.m_body->clear();
//     adjointKernel.m_body->addInstructions(instructions);
//     return adjointKernel;
//   }
//   virtual KernelBase ctrl(size_t ctrlIdx) {
//     // Copy this
//     KernelBase controlledKernel(this, "KernelName_CTRL");
//     // Use the controlled gate module of XACC to transform
//     // controlledKernel.m_body
//     auto ctrlKernel = quantum::controlledKernel(m_body, ctrlIdx);
//     // Set the body of the returned kernel instance.
//     controlledKernel.m_body = ctrlKernel;
//     return controlledKernel;
//   }
//   // Destructor:
//   // called right after the object invocation:
//   // e.g.
//   // Case 1: free-standing invocation:
//   //  ... code ...
//   // kernelFuncClass(abc);
//   // -> DTor called here
//   // ... code ...
//   // Cade 2: chaining
//   //  ... code ...
//   // kernelFuncClass(abc).adjoint();
//   // -> DTor of the Adjoint instance called here (m_usedAsCallable = true)
//   // hence adding the adjoint body to the global composite.
//   // -> DTor of the kernelFuncClass(abc) instance called here
//   (m_usedAsCallable
//   // = false) hence having no effect.
//   // ... code ...
//   virtual ~KernelBase() {
//     // This is used as a CALLABLE
//     if (m_usedAsCallable) {
//       // Add all instructions to the global program.
//       quantum::program->addInstructions(m_body->getInstructions());
//     }
//   }
//   // Default move CTor
//   KernelBase(KernelBase &&) = default;

// protected:
//   // Copy ctor:
//   // Deep copy of the CompositeInstruction to prevent dangling references.
//   KernelBase(KernelBase *other, const std::string &in_optional_newName = "")
//   {
//     const auto kernelName = in_optional_newName.empty() ?
//     other->m_body->name()
//                                                         :
//                                                         in_optional_newName;
//     auto provider = xacc::getIRProvider("quantum");
//     m_body = provider->createComposite(kernelName);
//     for (const auto &inst : other->m_body->getInstructions()) {
//       m_body->addInstruction(inst->clone());
//     }
//     m_qreg = other->m_qreg;
//     m_usedAsCallable = true;
//     // The copied kernel becomes *INACTIVE*
//     other->m_usedAsCallable = false;
//   }
//   // Denote if this instance was use as a *Callable*
//   // i.e.
//   // kernelFuncClass(qubitReg); => TRUE
//   // kernelFuncClass(qubitReg).adjoint(); => FALSE (on the original
//   // kernelFuncClass instance) but TRUE for the one returned by the adjoint()
//   // member function. This will allow arbitrary chaining: e.g.
//   // kernelFuncClass(qubitReg).adjoint().ctrl(k); only the last kernel
//   returned
//   // by ctrl() will be the *Callable*;
//   bool m_usedAsCallable;
//   // The XACC composite instruction described by this kernel body:
//   std::shared_ptr<xacc::CompositeInstruction> m_body;
//   // From kernel params:
//   xacc::internal_compiler::qreg m_qreg;
// };
// //// =================== END COMMON CODE ==============/////
// // The above code can be placed in a header file which is then injected.
// /// ============= ORIGINAL CODE ===================
// // Assume we are rewriting this:
// // __qpu__ void kernelFunc(qreg q, double angle) {
// //   H(q[0]);
// //   CNOT(q[0], q[1]);
// //   Rx(q[0], angle);
// // }
// /// =============  CODE GEN ======================////
// // kernel function: returns the class object.
// KernelBase kernelFunc(xacc::internal_compiler::qreg q, double angle) {
//   quantum::initialize("qpp", "KERNEL_NAME");
//   q.setNameAndStore("q");
//   auto provider = xacc::getIRProvider("quantum");
//   // Kernel name (function name)
//   // BODY to denote it's the original body
//   auto kernelBody = provider->createComposite("KernelName_BODY");
//   // Rewrite from function body:
//   // TODO: QRT functions to take an composite instruction arg
//   // hence added instructions to that composite.
//   // HACK: for testing, swapping the *GLOBAL* program.
//   auto cachedGlobalProgram = quantum::program;
//   // Set the program to this body composite,
//   // hence we can listen to all the QRT instructions below.
//   quantum::program = kernelBody;
//   // ======== QRT Code ===========
//   // Rewrite from the __qpu__ body
//   quantum::h(q[0]); // Ideally, we'll do quantum::h(q[0], kernelBody);
//   quantum::cnot(q[0], q[1]);
//   quantum::rx(q[0], angle);
//   // ======== QRT Code ===========
//   // Restore the global program
//   quantum::program = cachedGlobalProgram;
//   KernelBase instance(q, kernelBody);
//   return instance;
// }
// /// =============  END CODE GEN ======================////
// // Note: The most difficult part is to *CHANGE* the function signature from
// // returning *void* to returing *KernelBase*,
// // i.e. we need to be able to rewrite:
// // "__qpu__ void" ==> "__qpu__ KernelBase" (__qpu__ is handled by the
// // pre-processor) Possibility: the *qcor* script to do that before calling
// clang
// // ??
// //////////////////////////////////////////////////
// // TEST kernel-in-kernel
// // __qpu__ void nestedFunc(qreg q, double angle1, double angle2) {
// //   kernelFunc(q, angle1).adjoint();
// //   Ry(q[1], angle2);
// //   Measure(q[0]);
// // }
// /// =============  CODE GEN ======================////
// KernelBase nestedFunc(xacc::internal_compiler::qreg q, double angle1,
//                       double angle2) {
//   quantum::initialize("qpp", "KERNEL_NAME");
//   q.setNameAndStore("q");
//   auto provider = xacc::getIRProvider("quantum");
//   // Kernel name (function name)
//   // BODY to denote it's the original body
//   auto kernelBody = provider->createComposite("KernelName_BODY");
//   // Rewrite from function body:
//   auto cachedGlobalProgram = quantum::program;
//   // Set the program to this body composite,
//   // hence we can listen to all the QRT instructions below.
//   quantum::program = kernelBody;
//   // ======== QRT Code ===========
//   // Call other kernels (i.e. left unchanged)
//   // Support arbitrary chaining here as well.
//   kernelFunc(q, angle1).adjoint();
//   // Some more gates:
//   quantum::ry(q[1], angle2);
//   quantum::mz(q[0]);
//   // ======== QRT Code ===========
//   // Restore the global program
//   quantum::program = cachedGlobalProgram;
//   KernelBase instance(q, kernelBody);
//   return instance;
// }
// /// ============= END CODE GEN ======================////
// // Classical code:
// int main(int argc, char **argv) {
//   // Allocate 3 qubits
//   auto q = qalloc(3);
//   // Can try any of the following things:
//   // kernelFunc(q, 1.234);
//   // kernelFunc(q, 1.234).adjoint();
//   // kernelFunc(q, 1.234).ctrl(2);
//   // I'm crazy :)
//   // kernelFunc(q, 1.234).adjoint().ctrl(2).adjoint();
//   // Nested case:
//   // Note: we cannot `adjoint` or `control` the nestedFunc
//   // since it contains Measure (throw).
//   nestedFunc(q, 1.23, 4.56);
//   // This should include instructions from the above kernel,
//   // which is added when the Dtor is called.
//   std::cout << "Program: \n" << quantum::program->toString() << "\n";
//   // dump the results
//   q.print();
// }
} // namespace

static SyntaxHandlerRegistry::Add<QCORSyntaxHandler>
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ TEST(UnitaryTokenCollectorTester, checkSimple) {

  std::stringstream ss;
  auto xasm_tc = xacc::getService<qcor::TokenCollector>("unitary");
  xasm_tc->collect(*PP.get(), cached, {"a","b","c"}, ss);
  xasm_tc->collect(*PP.get(), cached, {"a"}, ss);
  std::cout << "heres the test\n";
  std::cout << ss.str() << "\n";

+3 −1
Original line number Diff line number Diff line
@@ -83,9 +83,11 @@ void UnitaryTokenCollector::collect(clang::Preprocessor &PP,
  }
  ss << "\n";

  std::cout << "HOWDY: " << var_name << ", " << bufferNames[0] << "\n";
  std::cout << ss.str() << "\n";
  // Add the qfast decomp and hook up to the qrt program.
  ss << "auto decomposed_program = "
        "qcor::__internal__::decompose_unitary(\"QFAST\", "
        "__internal__::decompose_unitary(\"QFAST\", "
     << var_name << ", " << bufferNames[0] << ".name());\n";

  ss << "parent_kernel->addInstruction(decomposed_program);\n";
Loading