diff --git a/quantum/gate/accelerators/SimulatedQubits.hpp b/quantum/gate/accelerators/SimulatedQubits.hpp index 89fd1f557ed53c15243341d3c11eca641f63f597..5a8159a31d24d1c2bcb7da7d57c42c0a40d1f444 100644 --- a/quantum/gate/accelerators/SimulatedQubits.hpp +++ b/quantum/gate/accelerators/SimulatedQubits.hpp @@ -35,7 +35,6 @@ #include <complex> #include "Tensor.hpp" #include <bitset> -#include "spdlog/spdlog.h" namespace xacc { @@ -169,20 +168,22 @@ public: } virtual void print() { - auto console = spdlog::get("console"); if (size() < TotalNumberOfQubits) { - for (int i = 0; i < bufferState.dimension(0); i++) { - console->info(std::bitset<TotalNumberOfQubits>(i).to_string().substr( - TotalNumberOfQubits - size(), TotalNumberOfQubits) + " -> " + for (int i = 0; i < bufferState.dimension(0); i++) { + XACCInfo( + std::bitset<TotalNumberOfQubits>(i).to_string().substr( + TotalNumberOfQubits - size(), + TotalNumberOfQubits) + " -> " + + std::to_string(std::real(bufferState(i)))); + } + } else { + for (int i = 0; i < bufferState.dimension(0); i++) { + + XACCInfo( + std::bitset<TotalNumberOfQubits>(i).to_string() + " -> " + std::to_string(std::real(bufferState(i)))); - } - } else { - for (int i = 0; i < bufferState.dimension(0); i++) { - - console->info(std::bitset<TotalNumberOfQubits>(i).to_string() - + " -> " + std::to_string(std::real(bufferState(i)))); - } - } + } + } } virtual ~SimulatedQubits() {} diff --git a/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.cpp b/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.cpp index edef14d36f9dce92f570677d01e47e38e8e59e15..552c3fedb8ef6156811b8a4fcce611d987cceaf0 100644 --- a/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.cpp +++ b/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.cpp @@ -55,39 +55,22 @@ bool FireTensorAccelerator::isValidBufferSize(const int NBits) { return NBits <= 10; } -/** - * The constructor, create tensor gates - */ -FireTensorAccelerator::FireTensorAccelerator() { - fire::Tensor<2, fire::EigenProvider, std::complex<double>> h(2, 2), cnot(4, - 4), I(2, 2), x(2, 2), p0(2, 2), p1(2, 2), z(2, 2); - h.setValues( - { { 1.0 / sqrt2, 1.0 / sqrt2 }, { 1.0 / sqrt2, -1.0 / sqrt2 } }); - cnot.setValues( { { 1, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { 0, 0, 1, - 0 } }); - x.setValues( { { 0, 1 }, { 1, 0 } }); - I.setValues( { { 1, 0 }, { 0, 1 } }); - p0.setValues( { { 1, 0 }, { 0, 0 } }); - p1.setValues( { { 0, 0 }, { 0, 1 } }); - z.setValues( { { 1, 0 }, { 0, -1 } }); - gates.insert(std::make_pair("h", h)); - gates.insert(std::make_pair("cnot", cnot)); - gates.insert(std::make_pair("x", x)); - gates.insert(std::make_pair("I", I)); - gates.insert(std::make_pair("p0", p0)); - gates.insert(std::make_pair("p1", p1)); - gates.insert(std::make_pair("z", z)); -} - void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, const std::shared_ptr<xacc::Function> kernel) { - using ProductList = std::vector<fire::Tensor<2, fire::EigenProvider, std::complex<double>>>; - using ComplexTensor = fire::Tensor<2, fire::EigenProvider, std::complex<double>>; + // Cast to what we know should be SimulatedQubits auto qubits = std::static_pointer_cast<SimulatedQubits<10>>(buffer); + if (!qubits) { + XACCError("Invalid derived AcceleratorBuffer passed to " + "FireTensorAccelerator. Must be of type SimulatedQubits<10>."); + } + + // Create a lambda for each type of gate we may encounter, + // each lambda must perform a gate-specific unitary + // on the qubits accelerator buffer. auto hadamard = - [&] (Hadamard& hGate) mutable { + [&] (Hadamard& hGate) { ComplexTensor h(2,2), I(2,2); I.setValues( { {1, 0}, {0, 1}}); h.setValues( @@ -136,7 +119,7 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, qubits->applyUnitary(localU); }; - auto x = [&] (X& xGate) mutable { + auto x = [&] (X& xGate) { ComplexTensor x(2,2), I(2,2); I.setValues( { { 1, 0 }, { 0, 1 } }); x.setValues( { { 0, 1 }, { 1, 0 } }); @@ -156,7 +139,7 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, qubits->applyUnitary(localU); }; - auto z = [&] (Z& zGate) mutable { + auto z = [&] (Z& zGate) { ComplexTensor z(2,2), I(2,2); I.setValues( { { 1, 0 }, { 0, 1 } }); z.setValues( { { 1, 0 }, { 0, -1 } }); @@ -178,8 +161,10 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, }; auto measure = [&](Measure& mGate) { - ComplexTensor I(2,2); + ComplexTensor I(2,2), p0(2,2), p1(2,2); I.setValues( { {1, 0}, {0, 1}}); + p0.setValues( { { 1, 0 }, { 0, 0 } }); + p1.setValues( { { 0, 0 }, { 0, 1 } }); auto actingQubits = mGate.bits(); ProductList productList; for (int j = 0; j < qubits->size(); j++) { @@ -188,7 +173,7 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, auto rho = qubits->getState() * qubits->getState(); - productList.at(actingQubits[0]) = gates.at("p0"); + productList.at(actingQubits[0]) = p0; auto Pi0 = productList.at(0); for (int i = 1; i < productList.size(); i++) { Pi0 = Pi0.kronProd(productList.at(i)); @@ -212,7 +197,7 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, qubits->normalize(); } else { result = 1; - productList.at(actingQubits[0]) = gates.at("p1"); + productList.at(actingQubits[0]) = p1; auto Pi1 = productList.at(0); for (int i = 1; i < productList.size(); i++) { Pi1 = Pi1.kronProd(productList.at(i)); @@ -221,222 +206,39 @@ void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, qubits->normalize(); } - std::cout << "Qubit " << actingQubits[0] << " measured to be a " << result << "\n"; - qubits->updateBit(actingQubits[0], result); }; auto cond = [&](ConditionalFunction& c) { auto qubit = c.getConditionalQubit(); auto bufResult = qubits->getAcceleratorBitState(qubit); - c.evaluate(bufResult == AcceleratorBitState::ONE ? 1 : 0); - std::cout << "Measurement on " << qubit << " was a " << - (bufResult == AcceleratorBitState::ONE ? 1 : 0) << "\n"; + if (bufResult == AcceleratorBitState::UNKNOWN) { + XACCError("Conditional Node is conditional on unmeasured qubit."); + } + auto bufResultAsInt = bufResult == AcceleratorBitState::ONE ? 1 : 0; + c.evaluate(bufResultAsInt); + XACCInfo("Measurement on " + std::to_string(qubit) + " was a " + + std::to_string(bufResultAsInt)); }; + // Create a Visitor that will execute our lambdas when + // we encounter one auto visitor = std::make_shared<GateInstructionVisitor>(hadamard, cnot, x, measure, z, cond); + // Our QIR is really a tree structure + // so create a pre-order tree traversal + // InstructionIterator to walk it InstructionIterator it(kernel); while (it.hasNext()) { + // Get the next node in the tree auto nextInst = it.next(); + + // If enabled, invoke the accept + // method which kicks off the visitor + // to execute the appropriate lambda. if (nextInst->isEnabled()) { - std::cout << "NEXTINST: " << nextInst->getName() << "\n"; nextInst->accept(visitor); - qubits->print(std::cout); - } - } - - - // Appy the unitary and update th state - std::cout << "\n\n"; - qubits->print(std::cout); - -} - -/** - * Execute the simulation. Requires both a valid SimulatedQubits buffer and - * Graph IR instance modeling the quantum circuit. - * - * @param ir - */ -void FireTensorAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, - const std::shared_ptr<xacc::IR> ir) { - - auto qubits = std::static_pointer_cast<SimulatedQubits<10>>(buffer); - - // Set the size - int nQubits = qubits->size(); - - // Cast to a GraphIR, if we can... - auto graphir = std::dynamic_pointer_cast<QuantumGraphIR>(ir); - if (!graphir) { - XACCError( - "Invalid IR - this Accelerator only accepts GraphIR<Graph<CircuitNode>>."); - } - - // Get the Graph and related info - std::vector<CircuitNode> gateOperations; - std::map<int, int> qubitIdToMeasuredResult; - auto graph = graphir->getGraph(); - int nNodes = graph.order(), layer = 1; - int finalLayer = graph.getVertexProperty<1>(nNodes - 1); - - // Get a vector of all gates - for (int i = 0; i < nNodes; i++) { - CircuitNode n; - n.properties = graph.getVertexProperties(i); - gateOperations.emplace_back(n); - } - - // Loop over all gates in the circuit - for (auto gate : gateOperations) { - - // Skip disabled gates... - if (!std::get<4>(gate.properties)) { - continue; - } - - // Create a list of nQubits Identity gates - std::vector<fire::Tensor<2, fire::EigenProvider, std::complex<double>>>productList; - for (int i = 0; i < nQubits; i++) { - productList.push_back(gates.at("I")); - } - - // Create a local U gate, initialized to identity - fire::Tensor<2, fire::EigenProvider, std::complex<double>> localU = - gates.at("I"); - - // Get the current gate anme - auto gateName = std::get<0>(gate.properties); - - // Get the qubits we're acting on... - auto actingQubits = std::get<3>(gate.properties); - - if (gateName == "conditional") { - - // If we hit a measured result then we - // need to figure out the measured qubit it - // depends on, then if its a 1, enable the disabled - // gates from this node to the next FinalState node - auto qubitWeNeed = std::get<3>(gate.properties)[0]; - auto qubitFound = qubitIdToMeasuredResult.find(qubitWeNeed); - if (qubitFound == qubitIdToMeasuredResult.end()) { - XACCError( - "Invalid conditional node - this qubit has not been measured."); - } - - auto result = qubitIdToMeasuredResult[qubitWeNeed]; - - auto currentNodeId = std::get<2>(gate.properties); - if (result == 1) { - // Walk over the next nodes until we hit a FinalState node - // set their enabled state to true - for (int i = currentNodeId + 1; i < nNodes; i++) { - // Once we hit the next final state node, then break out - if (std::get<0>(gateOperations[i].properties) - == "FinalState") { - break; - } - std::get<4>(gateOperations[i].properties) = true; - } - } - - } else if (gateName == "measure") { - - // get rho - outer product of state with itself - auto rho = qubits->getState() * qubits->getState(); - - // Create a total unitary for this layer of the circuit - productList.at(actingQubits[0]) = gates.at("p0"); - auto Pi0 = productList.at(0); - for (int i = 1; i < productList.size(); i++) { - Pi0 = Pi0.kronProd(productList.at(i)); - } - - // Get probability qubit is a 0 - double probZero = 0.0; - std::array<IndexPair, 1> contractionIndices; - contractionIndices[0] = std::make_pair(1, 0); - auto Prob0 = Pi0.contract(rho, contractionIndices); - for (int i = 0; i < Prob0.dimension(0); i++) - probZero += std::real(Prob0(i, i)); - - // Make the measurement random... - std::random_device rd; - std::mt19937 mt(rd()); - std::uniform_real_distribution<double> dist(0, 1.0); - int result; - auto val = dist(mt); - if (val < std::real(probZero)) { - result = 0; - qubits->applyUnitary(Pi0); - qubits->normalize(); - } else { - result = 1; - productList.at(actingQubits[0]) = gates.at("p1"); - // Create a total unitary for this layer of the circuit - auto Pi1 = productList.at(0); - for (int i = 1; i < productList.size(); i++) { - Pi1 = Pi1.kronProd(productList.at(i)); - } - qubits->applyUnitary(Pi1); - qubits->normalize(); - } - - // Record the measurement result - qubitIdToMeasuredResult.insert( - std::make_pair(actingQubits[0], result)); - - } else { - if (gateName != "FinalState" && gateName != "InitialState") { - // Regular Gate operations... - - if (actingQubits.size() == 1) { - - // If this is a one qubit gate, just replace - // the currect I in the list with the gate - productList.at(actingQubits[0]) = gates.at(gateName); - - // Create a total unitary for this layer of the circuit - localU = productList.at(0); - for (int i = 1; i < productList.size(); i++) { - localU = localU.kronProd(productList.at(i)); - } - - } else if (actingQubits.size() == 2) { - // If this is a 2 qubit gate, then we need t - // to construct Kron(P0, I, ..., I) + Kron(P1, I, ..., Gate, ..., I) - productList.at(actingQubits[0]) = gates.at("p0"); - localU = productList.at(0); - for (int i = 1; i < productList.size(); i++) { - localU = localU.kronProd(productList.at(i)); - } - - // Now create the second term in the sum - productList.at(actingQubits[0]) = gates.at("p1"); - productList.at(actingQubits[1]) = gates.at( - gateName == "cnot" ? "x" : "I"); - auto temp = productList.at(0); - for (int i = 1; i < productList.size(); i++) { - temp = temp.kronProd(productList.at(i)); - } - - // Sum them up - localU = localU + temp; - } else { - XACCError("Can only simulate one and two qubit gates."); - } - - // Make sure that localU is the correct size - assert( - localU.dimension(0) == std::pow(2, nQubits) - && localU.dimension(1) == std::pow(2, nQubits)); - - // Appy the unitary and update th state - qubits->applyUnitary(localU); - - } } } } diff --git a/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.hpp b/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.hpp index 83e21bbc98925b23a5a4debe8f0abf4621063a0d..a8eb5b37e359dc8106eaa0f548e992e759fb2d17 100644 --- a/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.hpp +++ b/quantum/gate/accelerators/firetensoraccelerator/FireTensorAccelerator.hpp @@ -43,8 +43,9 @@ namespace xacc { namespace quantum { double sqrt2 = std::sqrt(2.0); -using QuantumGraphIR = xacc::GraphIR<QuantumCircuit>; -using TensorMap = std::map<std::string, fire::Tensor<2, fire::EigenProvider, std::complex<double>>>; +using ProductList = std::vector<fire::Tensor<2, fire::EigenProvider, std::complex<double>>>; +using ComplexTensor = fire::Tensor<2, fire::EigenProvider, std::complex<double>>; + /** * The FireTensorAccelerator is an XACC Accelerator that simulates * gate based quantum computing circuits. It models the QPUGate Accelerator @@ -55,17 +56,36 @@ using TensorMap = std::map<std::string, fire::Tensor<2, fire::EigenProvider, st class FireTensorAccelerator : virtual public QPUGate { public: + /** + * Create, store, and return an AcceleratorBuffer with the given + * variable id string. This string serves as a unique identifier + * for future lookups and reuse of the AcceleratorBuffer. + * + * @param varId + * @return + */ std::shared_ptr<AcceleratorBuffer> createBuffer(const std::string& varId); + /** + * Create, store, and return an AcceleratorBuffer with the given + * variable id string and of the given number of bits. + * The string id serves as a unique identifier + * for future lookups and reuse of the AcceleratorBuffer. + * + * @param varId + * @param size + * @return + */ std::shared_ptr<AcceleratorBuffer> createBuffer(const std::string& varId, const int size); - virtual bool isValidBufferSize(const int NBits); - /** - * The constructor, create tensor gates + * Return true if this Accelerator can allocated + * NBits number of bits. + * @param NBits + * @return */ - FireTensorAccelerator(); + virtual bool isValidBufferSize(const int NBits); /** * Execute the simulation. Requires both a valid SimulatedQubits buffer and @@ -74,19 +94,12 @@ public: * @param ir */ virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer, const std::shared_ptr<xacc::Function> kernel); - virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer, const std::shared_ptr<xacc::IR> kernel); /** * The destructor */ virtual ~FireTensorAccelerator() {} -protected: - - /** - * Mapping of gate names to actual gate matrices. - */ - TensorMap gates; }; diff --git a/quantum/gate/accelerators/tests/FireTensorAcceleratorTester.cpp b/quantum/gate/accelerators/tests/FireTensorAcceleratorTester.cpp index 05d6f9e54f12202d205b6e12bc4409ccc338bab1..e9bc432cc44d9205c2d97472529ddd3ff9021eb1 100644 --- a/quantum/gate/accelerators/tests/FireTensorAcceleratorTester.cpp +++ b/quantum/gate/accelerators/tests/FireTensorAcceleratorTester.cpp @@ -34,7 +34,6 @@ #include <memory> #include <boost/test/included/unit_test.hpp> #include "FireTensorAccelerator.hpp" -#include "GraphIR.hpp" using namespace xacc::quantum; diff --git a/quantum/gate/compilers/scaffold/Scaffold.hpp b/quantum/gate/compilers/scaffold/Scaffold.hpp index 7071017da68ae1d30a85fa53a71d473471b53d6d..28d357be50ab0d03720dd2380c7fef3ef8c0938c 100644 --- a/quantum/gate/compilers/scaffold/Scaffold.hpp +++ b/quantum/gate/compilers/scaffold/Scaffold.hpp @@ -32,7 +32,7 @@ #define QUANTUM_IMPROVEDSCAFFOLDCOMPILER_HPP_ #include "Compiler.hpp" -#include "XACCError.hpp" +#include "Utils.hpp" #include <boost/algorithm/string.hpp> #include "../scaffold/ScaffoldASTConsumer.hpp" diff --git a/quantum/gate/compilers/scaffold/ScaffoldASTConsumer.cpp b/quantum/gate/compilers/scaffold/ScaffoldASTConsumer.cpp index f6b84463d8af9b94a0c1081dfa27e2a0fe41a297..8fa92ad1c524c2c7541ef439045cff861ff6102c 100644 --- a/quantum/gate/compilers/scaffold/ScaffoldASTConsumer.cpp +++ b/quantum/gate/compilers/scaffold/ScaffoldASTConsumer.cpp @@ -3,6 +3,9 @@ #include <iostream> #include <boost/algorithm/string.hpp> #include "ParameterizedGateInstruction.hpp" +#include "Utils.hpp" + +using namespace xacc; namespace scaffold { @@ -20,10 +23,10 @@ bool ScaffoldASTConsumer::VisitDecl(Decl *d) { auto varType = varDecl->getType().getAsString(); if (boost::contains(varType, "cbit")) { cbitVarName = varDecl->getDeclName().getAsString(); - std::cout << "Found " << cbitVarName << "\n"; +// std::cout << "Found " << cbitVarName << "\n"; } else if (boost::contains(varType, "qbit")) { qbitVarName = varDecl->getDeclName().getAsString(); - std::cout << "Found " << qbitVarName << "\n"; +// std::cout << "Found " << qbitVarName << "\n"; } } else if (isa<FunctionDecl>(d)) { auto c = cast<FunctionDecl>(d); @@ -42,7 +45,7 @@ bool ScaffoldASTConsumer::VisitStmt(Stmt *s) { std::string ifStr; llvm::raw_string_ostream ifS(ifStr); ifStmt->printPretty(ifS, nullptr, policy); - std::cout << "HELLO IF:\n" << ifS.str() << "\n"; +// std::cout << "HELLO IF:\n" << ifS.str() << "\n"; if (const auto binOp = llvm::dyn_cast<BinaryOperator>( ifStmt->getCond())) { @@ -52,21 +55,21 @@ bool ScaffoldASTConsumer::VisitStmt(Stmt *s) { std::string str; llvm::raw_string_ostream s(str); LHS->printPretty(s, nullptr, policy); - std::cout << "LHS IF: " << s.str() << "\n"; +// std::cout << "LHS IF: " << s.str() << "\n"; if (boost::contains(s.str(), cbitVarName)) { auto RHS = binOp->getRHS(); std::string rhsstr; llvm::raw_string_ostream rhss(rhsstr); RHS->printPretty(rhss, nullptr, policy); - std::cout << "RHS IF: " << rhss.str() << "\n"; +// std::cout << "RHS IF: " << rhss.str() << "\n"; auto thenCode = ifStmt->getThen(); std::string thenStr; llvm::raw_string_ostream thenS(thenStr); thenCode->printPretty(thenS, nullptr, policy); auto then = thenS.str(); - std::cout << "ThenStmt:\n" << then << "\n"; +// std::cout << "ThenStmt:\n" << then << "\n"; then.erase(std::remove(then.begin(), then.end(), '\t'), then.end()); boost::replace_all(then, "{\n", ""); @@ -75,12 +78,14 @@ bool ScaffoldASTConsumer::VisitStmt(Stmt *s) { boost::trim(then); int conditionalQubit = cbitRegToMeasuredQubit[s.str()]; - currentConditional = std::make_shared<xacc::quantum::ConditionalFunction>(conditionalQubit); + currentConditional = std::make_shared< + xacc::quantum::ConditionalFunction>( + conditionalQubit); std::vector<std::string> vec; boost::split(vec, then, boost::is_any_of("\n")); nCallExprToSkip = vec.size(); - std::cout << "NCALLEXPRTOSKIP = " << nCallExprToSkip << "\n"; +// std::cout << "NCALLEXPRTOSKIP = " << nCallExprToSkip << "\n"; } } } @@ -97,7 +102,6 @@ bool ScaffoldASTConsumer::VisitCallExpr(CallExpr* c) { if (t != NULL) { bool isParameterizedInst = false; auto fd = c->getDirectCallee(); - std::cout << "HOWDY: " << fd->getNameInfo().getAsString() << "\n"; auto gateName = fd->getNameInfo().getAsString(); std::vector<int> qubits; std::vector<double> params; @@ -106,7 +110,7 @@ bool ScaffoldASTConsumer::VisitCallExpr(CallExpr* c) { llvm::raw_string_ostream argstream(arg); i->printPretty(argstream, nullptr, policy); auto argStr = argstream.str(); - std::cout << "Arg: " << argstream.str() << "\n"; +// std::cout << "Arg: " << argstream.str() << "\n"; if (boost::contains(argStr, qbitVarName)) { boost::replace_all(argStr, qbitVarName, ""); @@ -134,13 +138,12 @@ bool ScaffoldASTConsumer::VisitCallExpr(CallExpr* c) { XACCError( "Can only handle 1 and 2 parameter gates... and only doubles... for now."); } - std::cout << "CREATED A " << gateName << " parameterized gate\n"; +// std::cout << "CREATED A " << gateName << " parameterized gate\n"; } else if (gateName != "MeasZ") { inst = xacc::quantum::GateInstructionRegistry::instance()->create( gateName, qubits); - std::cout << "CREATED A " << gateName << " gate\n"; } if (gateName != "MeasZ") { @@ -148,7 +151,7 @@ bool ScaffoldASTConsumer::VisitCallExpr(CallExpr* c) { if (nCallExprToSkip == 0) { function->addInstruction(inst); } else { - std::cout << "Adding Conditional Inst: " << gateName << "\n"; +// std::cout << "Adding Conditional Inst: " << gateName << "\n"; currentConditional->addInstruction(inst); nCallExprToSkip--; @@ -173,7 +176,6 @@ bool ScaffoldASTConsumer::VisitBinaryOperator(BinaryOperator * b) { llvm::raw_string_ostream rhss(rhsstr); rhs->printPretty(rhss, nullptr, policy); auto rhsString = rhss.str(); - std::cout << "HELLO BINOP: " << rhsString << "\n"; if (boost::contains(rhsString, "MeasZ")) { auto lhs = b->getLHS(); @@ -181,7 +183,7 @@ bool ScaffoldASTConsumer::VisitBinaryOperator(BinaryOperator * b) { llvm::raw_string_ostream lhss(lhsstr); lhs->printPretty(lhss, nullptr, policy); auto lhsString = lhss.str(); - std::cout << "HELLO BINOP LHS: " << lhsString << "\n"; +// std::cout << "HELLO BINOP LHS: " << lhsString << "\n"; boost::replace_all(lhsString, cbitVarName, ""); boost::replace_all(lhsString, "[", ""); @@ -201,9 +203,10 @@ bool ScaffoldASTConsumer::VisitBinaryOperator(BinaryOperator * b) { std::vector<int> { std::stoi(rhsString) }, std::stoi(lhsString)); - cbitRegToMeasuredQubit.insert(std::make_pair(lhsString, std::stoi(rhsString))); + cbitRegToMeasuredQubit.insert( + std::make_pair(lhss.str(), std::stoi(rhsString))); - std::cout << "ADDING A MEASUREMENT GATE " << lhsString << "\n"; +// std::cout << "ADDING A MEASUREMENT GATE " << lhss.str() << "\n"; function->addInstruction(inst); } diff --git a/quantum/gate/gateqir/GateFunction.hpp b/quantum/gate/gateqir/GateFunction.hpp index 6d95664927302d9a4ad951eaea48103658ea8489..7b7a30e899abb5320bcea7d0eeb48bc6b8c9ea05 100644 --- a/quantum/gate/gateqir/GateFunction.hpp +++ b/quantum/gate/gateqir/GateFunction.hpp @@ -32,7 +32,7 @@ #define QUANTUM_GATEQIR_QFUNCTION_HPP_ #include "Function.hpp" -#include "XACCError.hpp" +#include "Utils.hpp" namespace xacc { namespace quantum { diff --git a/quantum/gate/gateqir/GateInstructionVisitor.hpp b/quantum/gate/gateqir/GateInstructionVisitor.hpp index de54bf9b63eb8066b82a4ca16c9bdf932a72a068..fbd97cf77f2453c59b576bdeb5514cf9d573a427 100644 --- a/quantum/gate/gateqir/GateInstructionVisitor.hpp +++ b/quantum/gate/gateqir/GateInstructionVisitor.hpp @@ -31,6 +31,7 @@ #ifndef QUANTUM_GATE_GATEQIR_GATEINSTRUCTIONVISITOR_HPP_ #define QUANTUM_GATE_GATEQIR_GATEINSTRUCTIONVISITOR_HPP_ +#include "../../../xacc/utils/Utils.hpp" #include "Hadamard.hpp" #include "Measure.hpp" #include "CNOT.hpp" @@ -38,7 +39,6 @@ #include "Z.hpp" #include "X.hpp" #include "ConditionalFunction.hpp" -#include "XaccUtils.hpp" namespace xacc { namespace quantum { diff --git a/quantum/gate/gateqir/ParameterizedGateInstruction.hpp b/quantum/gate/gateqir/ParameterizedGateInstruction.hpp index b84ac1941704538639445f362ee6075b750f8f21..2c75038de472b67f9a379ea3e8d12f76fa3b3be5 100644 --- a/quantum/gate/gateqir/ParameterizedGateInstruction.hpp +++ b/quantum/gate/gateqir/ParameterizedGateInstruction.hpp @@ -31,9 +31,8 @@ #ifndef QUANTUM_GATE_GATEQIR_PARAMETERIZEDGATEINSTRUCTION_HPP_ #define QUANTUM_GATE_GATEQIR_PARAMETERIZEDGATEINSTRUCTION_HPP_ +#include "Utils.hpp" #include "GateInstruction.hpp" -#include "XACCError.hpp" -#include "XaccUtils.hpp" namespace xacc { namespace quantum { diff --git a/quantum/gate/gateqir/tests/FancyGateInstructionVisitor.cpp b/quantum/gate/gateqir/tests/FancyGateInstructionVisitor.cpp index 18b7387040d47f176f277cca08bbda963504af09..9192c106e6ee68f0ace30f1bb379826af0b0ae36 100644 --- a/quantum/gate/gateqir/tests/FancyGateInstructionVisitor.cpp +++ b/quantum/gate/gateqir/tests/FancyGateInstructionVisitor.cpp @@ -36,7 +36,7 @@ #include "InstructionIterator.hpp" #include "GateInstructionVisitor.hpp" -#include "XaccUtils.hpp" +#include "../../../../xacc/utils/Utils.hpp" using namespace xacc::quantum; diff --git a/xacc/XACC.hpp b/xacc/XACC.hpp index d6f6e1f463e476c07612dd6e93e90536479b2352..6acf96c8b5b847973e6c6fd03c3109fb7aa804dd 100644 --- a/xacc/XACC.hpp +++ b/xacc/XACC.hpp @@ -33,7 +33,7 @@ #include <iostream> #include <memory> -#include "spdlog/spdlog.h" +#include "Utils.hpp" #include "Program.hpp" namespace xacc { @@ -47,11 +47,14 @@ bool xaccFrameworkInitialized = false; * XACC API. */ void Initialize() { - auto console = spdlog::stdout_logger_mt("console", true); - console->info("[xacc] Initializing XACC Framework"); + auto console = spdlog::stdout_logger_mt("xacc-console", true); + XACCInfo("[xacc] Initializing XACC Framework"); auto compilerRegistry = xacc::CompilerRegistry::instance(); + auto acceleratorRegistry = xacc::AcceleratorRegistry::instance(); auto s = compilerRegistry->size(); - console->info("\t[xacc::compiler] XACC has " + std::to_string(s) + " Compiler" + (s==1 ? "" : "s") + " available."); + auto a = acceleratorRegistry->size(); + XACCInfo("[xacc::compiler] XACC has " + std::to_string(s) + " Compiler" + (s==1 ? "" : "s") + " available."); + XACCInfo("[xacc::accelerator] XACC has " + std::to_string(a) + " Accelerator" + (s==1 ? "" : "s") + " available."); xacc::xaccFrameworkInitialized = true; } @@ -67,23 +70,16 @@ std::shared_ptr<Accelerator> getAccelerator(const std::string& name) { } } -//template<typename ... RuntimeArgs> -//std::function<void(std::shared_ptr<AcceleratorBuffer>, RuntimeArgs...)> createKernel( -// const std::string& kernelName, std::shared_ptr<Accelerator> acc, -// const std::string& src) { -// xacc::Program p(acc, src); -// return p.getKernel<RuntimeArgs...>(kernelName); -//} - /** * This method should be called by clients to * clean up and finalize the XACC framework. It should * be called after using the XACC API. */ void Finalize() { - auto console = spdlog::get("console"); - console->info("[xacc] XACC Finalizing\n\tCleaning up Compiler Registry."); + XACCInfo("[xacc] XACC Finalizing\n[xacc::compiler] Cleaning up Compiler Registry." + "\n[xacc::accelerator] Cleaning up Accelerator Registry."); xacc::CompilerRegistry::instance()->destroy(); + xacc::AcceleratorRegistry::instance()->destroy(); xacc::xaccFrameworkInitialized = false; } } diff --git a/xacc/accelerator/Accelerator.hpp b/xacc/accelerator/Accelerator.hpp index 938c7e297a6267f9db2ad01a7e6ca770ef86cf67..5e622eb2c5972279d13cd1b0a4ba5ed17e3444a8 100644 --- a/xacc/accelerator/Accelerator.hpp +++ b/xacc/accelerator/Accelerator.hpp @@ -38,7 +38,6 @@ #include <bitset> #include "AcceleratorBuffer.hpp" #include "IRTransformation.hpp" -#include "XACCError.hpp" #include "Registry.hpp" #include "Function.hpp" diff --git a/xacc/accelerator/AcceleratorBuffer.hpp b/xacc/accelerator/AcceleratorBuffer.hpp index 5abd917d525d4b41cb860c05c2d3755c98068b78..b797b8065daab0c60df322d49a6113662b5cc69d 100644 --- a/xacc/accelerator/AcceleratorBuffer.hpp +++ b/xacc/accelerator/AcceleratorBuffer.hpp @@ -33,14 +33,13 @@ #include <string> #include <iostream> -#include "XACCError.hpp" +#include "Utils.hpp" enum class AcceleratorBitState {ZERO, ONE, UNKNOWN}; class AcceleratorBit { public: AcceleratorBit() :state(AcceleratorBitState::UNKNOWN){} void update(int zeroOrOne) { - std::cout << "HOWDY\n"; state = (zeroOrOne == 0 ? AcceleratorBitState::ZERO : AcceleratorBitState::ONE); } AcceleratorBitState getState() { diff --git a/xacc/program/Program.hpp b/xacc/program/Program.hpp index 7206cd238b72fec8ae6ce55da1f3d6491b3240bf..c640ac91e4ac6cad848cb9ef22e524af180b16e7 100644 --- a/xacc/program/Program.hpp +++ b/xacc/program/Program.hpp @@ -39,8 +39,8 @@ #include <boost/program_options.hpp> #include <boost/algorithm/string.hpp> #include <algorithm> -#include "XACCError.hpp" -#include "XaccUtils.hpp" + +#include "Utils.hpp" #include "Compiler.hpp" #include "Accelerator.hpp" @@ -121,12 +121,13 @@ protected: // Create the appropriate compiler compiler = xacc::CompilerRegistry::instance()->create(compilerToRun); - std::cout << "Executing " << compiler->getName() << " compiler.\n"; // Make sure we got a valid if (!compiler) { XACCError("Invalid Compiler.\n"); } + XACCInfo("Executing "+ compiler->getName() + " compiler."); + // Execute the compilation xaccIR = compiler->compile(src, accelerator); diff --git a/xacc/tests/CompilerTester.cpp b/xacc/tests/CompilerTester.cpp deleted file mode 100644 index 7b0b2fd17bab59d7110d6a64590b362fad04851c..0000000000000000000000000000000000000000 --- a/xacc/tests/CompilerTester.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*********************************************************************************** - * Copyright (c) 2016, UT-Battelle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the <organization> nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * Initial API and implementation - Alex McCaskey - * - **********************************************************************************/ -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE CompilerTester - -#include <boost/test/included/unit_test.hpp> -#include "Compiler.hpp" -#include "FakeCompiler.hpp" -#include "FakeAccelerator.hpp" - -using namespace xacc; - -BOOST_AUTO_TEST_CASE(checkKernelArgs) { - - auto acc = std::make_shared<FakeAccelerator>(); - auto qreg = acc->createBuffer("qreg", 3); - - const std::string src("__qpu__ void function(qbit qreg, double phi) {\n" - "}\n"); - - auto compiler = std::shared_ptr<Compiler>(new FakeCompiler()); - - auto a = std::dynamic_pointer_cast<Accelerator>(acc); - compiler->compile(src, a); - - auto asFake = std::dynamic_pointer_cast<FakeCompiler>(compiler); - -} diff --git a/xacc/tests/ProgramTester.cpp b/xacc/tests/ProgramTester.cpp index df3a6a83459c4c3d319311ff08e1e2dd3a033954..5278db10326f46adf229d97925e7ddb692d9c293 100644 --- a/xacc/tests/ProgramTester.cpp +++ b/xacc/tests/ProgramTester.cpp @@ -36,7 +36,6 @@ #include "FakeIR.hpp" #include "FakeAccelerator.hpp" #include "FireTensorAccelerator.hpp" -#include "XACCError.hpp" using namespace xacc; diff --git a/xacc/utils/Graph.hpp b/xacc/utils/Graph.hpp index 47c59e2fdcf52acd316b415db14f066cb757e91e..f508c6300e0ad7fcc5e12cfb99cbaf6da48f103e 100644 --- a/xacc/utils/Graph.hpp +++ b/xacc/utils/Graph.hpp @@ -40,7 +40,7 @@ #include <boost/algorithm/string.hpp> #include <boost/fusion/include/for_each.hpp> #include <numeric> -#include "XACCError.hpp" +#include "Utils.hpp" #include <utility> using namespace boost; diff --git a/xacc/utils/Registry.hpp b/xacc/utils/Registry.hpp index 304e1fa7c26504674ccfecebde619b4de2cc9143..73c09433f9ed45b65dbf15572009288c4dea966f 100644 --- a/xacc/utils/Registry.hpp +++ b/xacc/utils/Registry.hpp @@ -32,7 +32,7 @@ #define XACC_UTILS_REGISTRY_HPP_ #include "Singleton.hpp" -#include "XACCError.hpp" +#include "Utils.hpp" #include <map> #include <iostream> namespace xacc { diff --git a/xacc/utils/XaccUtils.hpp b/xacc/utils/Utils.hpp similarity index 82% rename from xacc/utils/XaccUtils.hpp rename to xacc/utils/Utils.hpp index 880c90abaf42f541b3fca5cb7202703befa4a52f..e28e95935d8b2f8273b6b9cbeab9ef62cd036252 100644 --- a/xacc/utils/XaccUtils.hpp +++ b/xacc/utils/Utils.hpp @@ -28,11 +28,12 @@ * Initial API and implementation - Alex McCaskey * **********************************************************************************/ -#ifndef XACC_UTILS_XACCUTILS_HPP_ -#define XACC_UTILS_XACCUTILS_HPP_ +#ifndef XACC_UTILS_UTILS_HPP_ +#define XACC_UTILS_UTILS_HPP_ #include <boost/bind.hpp> #include <boost/tokenizer.hpp> +#include "spdlog/spdlog.h" namespace xacc { @@ -110,5 +111,52 @@ tuple_runtime_get(Tuple&& t,size_t index){ throw std::runtime_error("Out of range"); return runtime_get_func_table<tuple_type>::table[index](t); } + + +class XACCException: public std::exception { +protected: + + std::string errorMessage; + +public: + + XACCException(std::string error) : + errorMessage(error) { + spdlog::get("xacc-console")->error(errorMessage); \ + } + + virtual const char * what() const throw () { + return errorMessage.c_str(); + } + + ~XACCException() throw () { + } +}; + +#define XACC_Abort do {std::abort();} while(0); + +class XACCInfoT { +public: + static void printInfo(const std::string& msg) { + auto c = spdlog::get("xacc-console"); + if (c) { + c->info(msg); + } + } +}; + +#define XACCError(errorMsg) \ + do { \ + using namespace xacc; \ + throw XACCException("\n\n XACC Error caught! \n\n" \ + + std::string(errorMsg) + "\n\n"); \ + } while(0) + +#define XACCInfo(infoMsg) \ + do { \ + xacc::XACCInfoT::printInfo(std::string(infoMsg)); \ + } while(0) + + } #endif diff --git a/xacc/utils/XACCError.hpp b/xacc/utils/XACCError.hpp deleted file mode 100644 index 8874854bba4126eb00eff22f872f092d2915d6b8..0000000000000000000000000000000000000000 --- a/xacc/utils/XACCError.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/*********************************************************************************** - * Copyright (c) 2017, UT-Battelle - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the xacc nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * Initial API and implementation - Alex McCaskey - * - **********************************************************************************/ -#ifndef UTILS_XACCERROR_HPP_ -#define UTILS_XACCERROR_HPP_ - -#include <exception> -#include <sstream> -#include "spdlog/spdlog.h" - -namespace xacc { - -class XACCException: public std::exception { -protected: - - std::string errorMessage; - -public: - - XACCException(std::string error) : - errorMessage(error) { - spdlog::get("console")->error(errorMessage); \ - } - - virtual const char * what() const throw () { - return errorMessage.c_str(); - } - - ~XACCException() throw () { - } -}; - -#define XACC_Abort do {std::abort();} while(0); - -#define XACCError(errorMsg) \ - do { \ - using namespace xacc; \ - throw XACCException("\n\n XACC Error caught! \n\n" \ - + std::string(errorMsg) + "\n\n"); \ - } while(0) - -} -#endif