Skip to content
Snippets Groups Projects
Commit ed8c28ae authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Fixed measurement conditional graph ordering bug (#3)

parent 008c21a1
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
......@@ -86,6 +86,7 @@ protected:
* Reference to potential conditional code
*/
std::vector<std::string> conditionalCodeSegments;
std::vector<int> conditionalCodeSegmentActingQubits;
};
......
......@@ -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
......
......@@ -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;
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment