diff --git a/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp b/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp index 07db02ab16bc6d978073bfc718760a46c53fdd2e..5fb06a80fd2caf5abfcd09c15e123d3d6f9e3065 100644 --- a/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp +++ b/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp @@ -49,11 +49,47 @@ void ScaffoldCompiler::modifySource() { kernelSource.erase(kernelSource.find("__qpu__"), 7); kernelSource = std::string("module ") + kernelSource; - std::string qubitAllocationLine;// = " qbit qreg[3];\n"; + std::string qubitAllocationLine, cbitAllocationLine;// = " qbit qreg[3];\n"; std::regex qbitName("qbit\\s.*"); qubitAllocationLine = (*std::sregex_iterator(kernelSource.begin(), kernelSource.end(), qbitName)).str() + "\n"; + std::vector<std::string> splitQbit; + boost::split(splitQbit, qubitAllocationLine, boost::is_any_of(" ")); + auto qbitVarName = splitQbit[1].substr(0, splitQbit[1].find_first_of("[")); + + std::regex cbitName("cbit\\s.*"); + cbitAllocationLine = (*std::sregex_iterator(kernelSource.begin(), kernelSource.end(), + cbitName)).str() + "\n"; + std::vector<std::string> splitCbit; + boost::split(splitCbit, cbitAllocationLine, boost::is_any_of(" ")); + auto cbitVarName = splitCbit[1].substr(0, splitCbit[1].find_first_of("[")); + + std::regex measurements(".*Meas.*"); + std::map<int, int> cbitToQubit; + for (auto i = std::sregex_iterator(kernelSource.begin(), kernelSource.end(), + measurements); i != std::sregex_iterator(); ++i) { + auto measurement = (*i).str(); + boost::trim(measurement); + + boost::erase_all(measurement, "MeasZ"); + boost::erase_all(measurement, "("); + boost::erase_all(measurement, ")"); + boost::erase_all(measurement, cbitVarName); + boost::erase_all(measurement, qbitVarName); + // Should now have [#] = [#] + boost::erase_all(measurement, "["); + boost::erase_all(measurement, "]"); + + std::vector<std::string> splitVec; + boost::split(splitVec, measurement, boost::is_any_of("=")); + auto cbit = splitVec[0]; + auto qbit = splitVec[1]; + boost::trim(cbit); + boost::trim(qbit); + + cbitToQubit.insert(std::make_pair(std::stoi(cbit), std::stoi(qbit))); + } // conditional on measurements // FIXME FOR NOW WE ONLY ACCEPT format @@ -73,12 +109,28 @@ void ScaffoldCompiler::modifySource() { counter++; ifLines.push_back(ifLine + ";\n"); - } - for (auto s : conditionalCodeSegments) { - std::cout << s << "\n"; + // Also get which cbit this conditional code belongs to + int measurementGateId = -1; + for (auto s : splitVec) { + if (boost::contains(s, cbitVarName)) { + boost::erase_all(s, "("); + + boost::erase_all(s, cbitVarName); + boost::erase_all(s, "["); + boost::erase_all(s, "]"); + + conditionalCodeSegmentActingQubits.push_back(cbitToQubit[std::stoi(s)]); + + break; + } + } + } + // Erase the if lines from the main source + // they are going to be represented with + // conditional graphs. for (auto s : ifLines) { auto idx = kernelSource.find(s); kernelSource.erase(idx, s.size()); @@ -94,7 +146,7 @@ void ScaffoldCompiler::modifySource() { kernelSource = kernelSource + std::string("\nint main() {\n ") + fName + std::string(");\n}"); - std::cout << "\n" << kernelSource << "\n"; +// std::cout << "\n" << kernelSource << "\n"; } std::shared_ptr<IR> ScaffoldCompiler::compile() { @@ -111,7 +163,7 @@ std::shared_ptr<IR> ScaffoldCompiler::compile() { // Generate a GraphIR instance, ie a graph // tensor references making up this QASM - std::cout << "Flat QASM: \n" << qasm << "\n"; +// std::cout << "Flat QASM: \n" << qasm << "\n"; // Get the Qasm as a Graph... auto circuitGraph = QasmToGraph::getCircuitGraph(qasm); @@ -122,6 +174,8 @@ std::shared_ptr<IR> ScaffoldCompiler::compile() { // the addition of a COND conditional node that will enable the // conditional nodes if the measured cbit is a 1. + // Get measurement acting qubits + // So a COND node needs to know the gate id of the measurement gate // and the nodes to mark enabled if the measurement is a 1, if (!conditionalCodeSegments.empty()) { @@ -132,7 +186,8 @@ std::shared_ptr<IR> ScaffoldCompiler::compile() { condGraphs.push_back(g); } - QasmToGraph::linkConditionalQasm(circuitGraph, condGraphs); + QasmToGraph::linkConditionalQasm(circuitGraph, condGraphs, + conditionalCodeSegmentActingQubits); } // Create a GraphIR instance from that graph diff --git a/quantum/gate/compilers/scaffold/ScaffoldCompiler.hpp b/quantum/gate/compilers/scaffold/ScaffoldCompiler.hpp index 8c641ed512e68b9912696f9decf952ad29d12d76..a8e6ca818d3b5b5bb83627366a5224efd144075e 100644 --- a/quantum/gate/compilers/scaffold/ScaffoldCompiler.hpp +++ b/quantum/gate/compilers/scaffold/ScaffoldCompiler.hpp @@ -86,6 +86,7 @@ protected: * Reference to potential conditional code */ std::vector<std::string> conditionalCodeSegments; + std::vector<int> conditionalCodeSegmentActingQubits; }; diff --git a/quantum/gate/utils/QasmToGraph.hpp b/quantum/gate/utils/QasmToGraph.hpp index 000e83188af1fd13c5d5f9a3e05f4e09d0fcff8b..80e8b15a50dd3ac419ee598402304d070f83d0bc 100644 --- a/quantum/gate/utils/QasmToGraph.hpp +++ b/quantum/gate/utils/QasmToGraph.hpp @@ -214,7 +214,7 @@ public: * @param conditionalGraphs */ static void linkConditionalQasm(qci::common::Graph<CircuitNode>& mainGraph, - std::vector<qci::common::Graph<CircuitNode>> conditionalGraphs) { + std::vector<qci::common::Graph<CircuitNode>>& conditionalGraphs, std::vector<int>& conditionalQubits) { // At this point we have a main circuit graph, // and one or more smaller conditional graphs (each with @@ -224,18 +224,7 @@ public: // pull out the gate vertices (skip initial final state nodes) // and add them to the main graph after some conditional nodes - // NOTE We assume that the ith conditionalGraph corresponds to the ith - // measurement gate... WRONG!!!! - std::vector<int> measurementIds; - std::vector<std::vector<int>>measurementQubits; - for (int i = 0; i < mainGraph.order(); i++) { - if (mainGraph.getVertexProperty<0>(i) == "measure") { - measurementIds.push_back(mainGraph.getVertexProperty<2>(i)); - measurementQubits.push_back(mainGraph.getVertexProperty<3>(i)); - } - } - - assert (measurementIds.size() == conditionalGraphs.size()); + assert (conditionalQubits.size() == conditionalGraphs.size()); int counter = 0; int finalIdMainGraph = mainGraph.getVertexProperty<2>(mainGraph.order() - 1); @@ -250,8 +239,8 @@ public: for (auto g : conditionalGraphs) { CircuitNode node; std::get<0>(node.properties) = "conditional"; - std::get<2>(node.properties) = id;//measurementIds[counter]; - std::get<3>(node.properties) = measurementQubits[counter]; + std::get<2>(node.properties) = id; + std::get<3>(node.properties) = std::vector<int> {conditionalQubits[counter]}; mainGraph.addVertex(node); // Connect the main graph to the cond node diff --git a/xacc/program/Program.hpp b/xacc/program/Program.hpp index 7d0447fd3bf78a6e93f34b15ef129dc6e968113d..2dfcb31fa67a04cfa99e1e150dcd67f39a0de492 100644 --- a/xacc/program/Program.hpp +++ b/xacc/program/Program.hpp @@ -64,7 +64,6 @@ std::vector<IRTransformation> getAcceleratorIndependentTransformations( * Accelerator reference to be used and kernel source * code at construction time. */ -//template<typename AccType> class Program { protected: @@ -147,7 +146,6 @@ public: auto bitTypeStr = compiler->getBitType(); auto nBits = accelerator->getAllocationSize(); auto varName = accelerator->getVariableName(); - std::cout << "HELLO WORLD: " << nBits << ", " << varName << "\n"; std::string bitAllocationSrc = bitTypeStr + " " + varName + "[" + std::to_string(nBits) + "];\n"; @@ -202,7 +200,6 @@ public: std::function<void(RuntimeArgs...)> getKernel(const std::string& name, RuntimeArgs ... args) { return [&]() { - std::cout << "HELLO WORLD FROM KERNEL\n"; accelerator->execute(xaccIR, args...); return; };