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

updated staq tpl with latest bug fix, minor cleanup throughout



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 8db62292
Pipeline #118352 passed with stage
in 13 minutes and 14 seconds
...@@ -27,18 +27,16 @@ class MitiqDecorator(xacc.AcceleratorDecorator): ...@@ -27,18 +27,16 @@ class MitiqDecorator(xacc.AcceleratorDecorator):
def noisy_sim(circ : QuantumCircuit): def noisy_sim(circ : QuantumCircuit):
# Convert circ to a CompositeInstruction # Convert circ to a CompositeInstruction
out_src = circ.qasm() out_src = circ.qasm()
# print('hello src:\n', out_src)
out_prog = self.openqasm_compiler.compile(out_src).getComposites()[0] out_prog = self.openqasm_compiler.compile(out_src).getComposites()[0]
# print('after compile:\n', out_prog.toString())
# Execute on a tmp buffer # Execute on a tmp buffer
tmp_buffer = xacc.qalloc(buffer.size()) tmp_buffer = xacc.qalloc(buffer.size())
self.decoratedAccelerator.execute(tmp_buffer, out_prog) self.decoratedAccelerator.execute(tmp_buffer, out_prog)
# tmp_buffer.addExtraInfo('exp-val-z', tmp_buffer.getExpectationValueZ())
# record the noisy exp val # record the noisy exp val
buffer.addExtraInfo('noisy-exp-val-z', tmp_buffer.getExpectationValueZ()) buffer.addExtraInfo('noisy-exp-val-z', tmp_buffer.getExpectationValueZ())
buffer.appendChild('mitiq-noisy-exec-'+buffer.name(), tmp_buffer) # buffer.appendChild('mitiq-noisy-exec-'+buffer.name(), tmp_buffer)
return tmp_buffer.getExpectationValueZ() return tmp_buffer.getExpectationValueZ()
# easiest thing to do is map to Qiskit # easiest thing to do is map to Qiskit
...@@ -47,22 +45,27 @@ class MitiqDecorator(xacc.AcceleratorDecorator): ...@@ -47,22 +45,27 @@ class MitiqDecorator(xacc.AcceleratorDecorator):
# Create a QuantumCircuit # Create a QuantumCircuit
circuit = QuantumCircuit.from_qasm_str(src) circuit = QuantumCircuit.from_qasm_str(src)
# print(circuit.qasm()) # print('New Circuit:\n', circuit.qasm())
fixed_exp = mitiq.execute_with_zne(circuit, noisy_sim) fixed_exp = mitiq.execute_with_zne(circuit, noisy_sim)
# print(fixed_exp) # print(fixed_exp)
buffer.addExtraInfo('exp-val-z', fixed_exp) buffer.addExtraInfo('exp-val-z', fixed_exp)
return return
def execute(self, buffer, programs): def execute(self, buffer, programs):
print('[mitiq] executing Mitiq')
# Translate IR to a Qobj Json String # Translate IR to a Qobj Json String
if isinstance(programs, list) and len(programs) > 1: if isinstance(programs, list) and len(programs) > 1:
for p in programs: for p in programs:
tmpBuffer = xacc.qalloc(buffer.size()) tmpBuffer = xacc.qalloc(buffer.size())
tmpBuffer.setName(p.name()) tmpBuffer.setName(p.name())
self.execute_single(tmpBuffer, p) self.execute_single(tmpBuffer, p)
print('\t[mitiq] <', p.name(), '>_noisy = ', tmpBuffer['noisy-exp-val-z'] ,' -> <', p.name(), '>_fixed = ', tmpBuffer['exp-val-z'])
buffer.appendChild(p.name(),tmpBuffer) buffer.appendChild(p.name(),tmpBuffer)
# print(tmpBuffer)
else: else:
if isinstance(programs, list): if isinstance(programs, list):
programs = programs[0] programs = programs[0]
self.execute_single(buffer, programs) self.execute_single(buffer, programs)
# print('returning from mitiq')
return
...@@ -163,6 +163,7 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const { ...@@ -163,6 +163,7 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
// posts the energy automatically at a given key // posts the energy automatically at a given key
// on the buffer extra info. // on the buffer extra info.
double energy = identityCoeff; double energy = identityCoeff;
double variance = 0.0;
// Create buffer child for the Identity term // Create buffer child for the Identity term
auto idBuffer = xacc::qalloc(buffer->size()); auto idBuffer = xacc::qalloc(buffer->size());
...@@ -194,12 +195,27 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const { ...@@ -194,12 +195,27 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
for (int i = 0; i < nInstructionsEnergy; i++) { // compute energy for (int i = 0; i < nInstructionsEnergy; i++) { // compute energy
auto expval = buffers[i]->getExpectationValueZ(); auto expval = buffers[i]->getExpectationValueZ();
if (!got_aggregate) if (!got_aggregate) {
energy += expval * coefficients[i]; energy += expval * coefficients[i];
if (!buffers[i]->getMeasurementCounts().empty()) {
auto paulvar = 1. - expval * expval;
buffers[i]->addExtraInfo("pauli-variance", paulvar);
variance += coefficients[i] * coefficients[i] * paulvar;
}
}
buffers[i]->addExtraInfo("coefficient", coefficients[i]); buffers[i]->addExtraInfo("coefficient", coefficients[i]);
buffers[i]->addExtraInfo("kernel", fsToExec[i]->name()); buffers[i]->addExtraInfo("kernel", fsToExec[i]->name());
buffers[i]->addExtraInfo("exp-val-z", expval); buffers[i]->addExtraInfo("exp-val-z", expval);
buffers[i]->addExtraInfo("parameters", x); buffers[i]->addExtraInfo("parameters", x);
if (!buffers[i]->getMeasurementCounts().empty()) {
int n_shots = 0;
for (auto [k, v] : buffers[i]->getMeasurementCounts()) {
n_shots += v;
}
buffers[i]->addExtraInfo("energy-standard-deviation",
std::sqrt(variance / n_shots));
}
buffer->appendChild(fsToExec[i]->name(), buffers[i]); buffer->appendChild(fsToExec[i]->name(), buffers[i]);
} }
...@@ -225,6 +241,11 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const { ...@@ -225,6 +241,11 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
for (int i = 0; i < fsToExec.size(); i++) { for (int i = 0; i < fsToExec.size(); i++) {
auto expval = buffers[i]->getExpectationValueZ(); auto expval = buffers[i]->getExpectationValueZ();
energy += expval * coefficients[i]; energy += expval * coefficients[i];
if (!buffers[i]->getMeasurementCounts().empty()) {
auto paulvar = 1. - expval * expval;
buffers[i]->addExtraInfo("pauli-variance", paulvar);
variance += coefficients[i] * coefficients[i] * paulvar;
}
} }
for (int i = 0; i < fsToExec.size(); i++) { for (int i = 0; i < fsToExec.size(); i++) {
...@@ -233,6 +254,16 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const { ...@@ -233,6 +254,16 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
buffers[i]->addExtraInfo("exp-val-z", buffers[i]->addExtraInfo("exp-val-z",
buffers[i]->getExpectationValueZ()); buffers[i]->getExpectationValueZ());
buffers[i]->addExtraInfo("parameters", x); buffers[i]->addExtraInfo("parameters", x);
if (!buffers[i]->getMeasurementCounts().empty()) {
int n_shots = 0;
for (auto [k, v] : buffers[i]->getMeasurementCounts()) {
n_shots += v;
}
buffers[i]->addExtraInfo("energy-standard-deviation",
std::sqrt(variance / n_shots));
}
buffer->appendChild(fsToExec[i]->name(), buffers[i]); buffer->appendChild(fsToExec[i]->name(), buffers[i]);
} }
} }
...@@ -305,6 +336,7 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer, ...@@ -305,6 +336,7 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer,
// posts the energy automatically at a given key // posts the energy automatically at a given key
// on the buffer extra info. // on the buffer extra info.
double energy = identityCoeff; double energy = identityCoeff;
double variance = 0.0;
// Create buffer child for the Identity term // Create buffer child for the Identity term
auto idBuffer = xacc::qalloc(buffer->size()); auto idBuffer = xacc::qalloc(buffer->size());
...@@ -334,6 +366,11 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer, ...@@ -334,6 +366,11 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer,
for (int i = 0; i < fsToExec.size(); i++) { // compute energy for (int i = 0; i < fsToExec.size(); i++) { // compute energy
auto expval = buffers[i]->getExpectationValueZ(); auto expval = buffers[i]->getExpectationValueZ();
energy += expval * coefficients[i]; energy += expval * coefficients[i];
if (!buffers[i]->getMeasurementCounts().empty()) {
auto paulvar = 1. - expval * expval;
buffers[i]->addExtraInfo("pauli-variance", paulvar);
variance += coefficients[i] * coefficients[i] * paulvar;
}
} }
for (int i = 0; i < fsToExec.size(); i++) { for (int i = 0; i < fsToExec.size(); i++) {
...@@ -341,6 +378,15 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer, ...@@ -341,6 +378,15 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer,
buffers[i]->addExtraInfo("kernel", fsToExec[i]->name()); buffers[i]->addExtraInfo("kernel", fsToExec[i]->name());
buffers[i]->addExtraInfo("exp-val-z", buffers[i]->getExpectationValueZ()); buffers[i]->addExtraInfo("exp-val-z", buffers[i]->getExpectationValueZ());
buffers[i]->addExtraInfo("parameters", x); buffers[i]->addExtraInfo("parameters", x);
if (!buffers[i]->getMeasurementCounts().empty()) {
int n_shots = 0;
for (auto [k, v] : buffers[i]->getMeasurementCounts()) {
n_shots += v;
}
buffers[i]->addExtraInfo("energy-standard-deviation",
std::sqrt(variance / n_shots));
}
buffer->appendChild(fsToExec[i]->name(), buffers[i]); buffer->appendChild(fsToExec[i]->name(), buffers[i]);
} }
} }
......
...@@ -73,37 +73,10 @@ void AerAccelerator::initialize(const HeterogeneousMap &params) { ...@@ -73,37 +73,10 @@ void AerAccelerator::initialize(const HeterogeneousMap &params) {
} }
if (params.stringExists("backend")) { if (params.stringExists("backend")) {
auto ibm = xacc::getAccelerator("ibm:" + params.getString("backend")); auto ibm_noise_model = xacc::getService<NoiseModel>("IBM");
physical_backend_properties = ibm->getProperties(); ibm_noise_model->initialize(params);
auto props = physical_backend_properties.get<std::string>("total-json"); auto json_str = ibm_noise_model->toJson();
auto props_json = nlohmann::json::parse(props); noise_model = nlohmann::json::parse(json_str);
connectivity = ibm->getConnectivity();
// nlohmann::json errors_json;
std::vector<nlohmann::json> elements;
std::size_t qbit = 0;
for (auto it = props_json["qubits"].begin();
it != props_json["qubits"].end(); ++it) {
std::vector<double> value{(*(it->begin() + 5))["value"].get<double>(),
(*(it->begin() + 4))["value"].get<double>()};
std::vector<std::vector<double>> probs{{1 - value[0], value[0]},
{value[1], 1 - value[1]}};
nlohmann::json element;
element["type"] = "roerror";
element["operations"] = std::vector<std::string>{"measure"};
element["probabilities"] = probs;
element["gate_qubits"] = std::vector<std::vector<std::size_t>>{{qbit}};
elements.push_back(element);
qbit++;
}
noise_model["errors"] = elements;
// noise_model["x90_gates"] = std::vecto
// std::cout << "NoiseModelJson:\n" << noise_model.dump(4) << "\n";
} else if (params.stringExists("noise-model")) { } else if (params.stringExists("noise-model")) {
std::string noise_model_str = params.getString("noise-model"); std::string noise_model_str = params.getString("noise-model");
// Check if this is a file name // Check if this is a file name
...@@ -152,7 +125,9 @@ void AerAccelerator::execute( ...@@ -152,7 +125,9 @@ void AerAccelerator::execute(
nlohmann::json j = nlohmann::json::parse(qobj_str)["qObject"]; nlohmann::json j = nlohmann::json::parse(qobj_str)["qObject"];
j["config"]["shots"] = m_shots; j["config"]["shots"] = m_shots;
j["config"]["noise_model"] = noise_model; j["config"]["noise_model"] = noise_model;
xacc::info("Qobj:\n" + j.dump(2));
// xacc::set_verbose(true);
// xacc::info("Shots Qobj:\n" + j.dump(2));
auto results_json = nlohmann::json::parse( auto results_json = nlohmann::json::parse(
AER::controller_execute_json<AER::Simulator::QasmController>(j.dump())); AER::controller_execute_json<AER::Simulator::QasmController>(j.dump()));
...@@ -193,11 +168,18 @@ void AerAccelerator::execute( ...@@ -193,11 +168,18 @@ void AerAccelerator::execute(
auto qobj_str = xacc_to_qobj->translate(tmp); auto qobj_str = xacc_to_qobj->translate(tmp);
nlohmann::json j = nlohmann::json::parse(qobj_str)["qObject"]; nlohmann::json j = nlohmann::json::parse(qobj_str)["qObject"];
j["config"]["noise_model"] = noise_model;
// xacc::info("StateVec Qobj:\n" + j.dump(2));
auto results_json = nlohmann::json::parse( auto results_json = nlohmann::json::parse(
AER::controller_execute_json<AER::Simulator::StatevectorController>( AER::controller_execute_json<AER::Simulator::StatevectorController>(
j.dump())); j.dump()));
if (results_json["status"].get<std::string>().find("ERROR") != std::string::npos) {
std::cout << results_json["status"].get<std::string>() << "\n";
xacc::error("Aer Error: " + results_json["status"].get<std::string>());
}
auto results = *results_json["results"].begin(); auto results = *results_json["results"].begin();
auto state_vector = results["data"]["statevector"] auto state_vector = results["data"]["statevector"]
......
...@@ -192,11 +192,20 @@ std::shared_ptr<IR> StaqCompiler::compile(const std::string &src, ...@@ -192,11 +192,20 @@ std::shared_ptr<IR> StaqCompiler::compile(const std::string &src,
// std::cout << " HELLO:\n" << _src << "\n"; // std::cout << " HELLO:\n" << _src << "\n";
using namespace staq; using namespace staq;
auto prog = parser::parse_string(_src); ast::ptr<ast::Program> prog;
transformations::desugar(*prog); try {
transformations::synthesize_oracles(*prog); prog = parser::parse_string(src);
transformations::desugar(*prog);
transformations::synthesize_oracles(*prog);
} catch (std::exception &e) {
std::stringstream ss;
ss << e.what();
ss << "\nXACC Error in Staq Compiler, here was the src:\n" << src << "\n";
xacc::error(ss.str());
}
if (run_staq_optimize) optimization::simplify(*prog); if (run_staq_optimize)
optimization::simplify(*prog);
// at this point we have to find out if we have any ancilla // at this point we have to find out if we have any ancilla
// registers // registers
......
...@@ -36,7 +36,6 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program, ...@@ -36,7 +36,6 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
return; return;
} }
// First get total number of qubits on device // First get total number of qubits on device
std::set<int> qbitIdxs; std::set<int> qbitIdxs;
auto connectivity = qpu->getConnectivity(); auto connectivity = qpu->getConnectivity();
...@@ -62,12 +61,21 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program, ...@@ -62,12 +61,21 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
auto staq = xacc::getCompiler("staq"); auto staq = xacc::getCompiler("staq");
auto src = staq->translate(program); auto src = staq->translate(program);
// std::cout << "HELLO WORLD:\n" << src << "\n";
// parse that to get staq ast // parse that to get staq ast
auto prog = parser::parse_string(src); ast::ptr<ast::Program> prog;
try {
prog = parser::parse_string(src);
} catch (std::exception &e) {
std::stringstream ss;
ss << e.what();
ss << "\nXACC Error in Staq Swap Short, here was the src:\n" << src << "\n";
xacc::error(ss.str());
}
mapping::Device device(qpu->getSignature(), nQubits, adj);
mapping::Device device(qpu->getSignature(), nQubits,
adj);
// map qreg_NAME -> q // map qreg_NAME -> q
auto layout = mapping::compute_basic_layout(device, *prog); auto layout = mapping::compute_basic_layout(device, *prog);
mapping::apply_layout(layout, device, *prog); mapping::apply_layout(layout, device, *prog);
...@@ -80,7 +88,9 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program, ...@@ -80,7 +88,9 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
prog->pretty_print(ss); prog->pretty_print(ss);
src = ss.str(); src = ss.str();
// std::cout << "AGAIN\n" << src << "\n";
auto ir = staq->compile(src); auto ir = staq->compile(src);
// std::cout << "PASSED HERE\n";
// reset the program and add optimized instructions // reset the program and add optimized instructions
program->clear(); program->clear();
......
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
/**
* \file ast/ast.hpp
*/
#include "ast/visitor.hpp"
#include "ast/base.hpp"
#include "ast/expr.hpp"
#include "ast/stmt.hpp"
#include "ast/decl.hpp"
#include "ast/program.hpp"
#include "ast/semantic.hpp"
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* \file ast/base.hpp
* \brief openQASM syntax trees
*/
#pragma once
#include "parser/position.hpp"
#include "visitor.hpp"
#include <set>
#include <memory>
namespace staq {
namespace ast {
template <typename T>
using ptr = std::unique_ptr<T>;
using symbol = std::string;
/**
* \class staq::ast::ASTNode
* \brief Base class for AST nodes
*/
class ASTNode {
static int& max_uid_() {
static int v;
return v;
} ///< the maximum uid that has been assigned
protected:
const int uid_; ///< the node's unique ID
const parser::Position pos_; ///< the node's source code position
public:
ASTNode(parser::Position pos) : uid_(++max_uid_()), pos_(pos) {}
virtual ~ASTNode() = default;
/**
* \brief Get the ID of the node
*
* \return The node's unique ID
*/
int uid() const { return uid_; }
/**
* \brief Get the position of the node
*
* \return The node's position in source
*/
parser::Position pos() const { return pos_; }
/**
* \brief Provides dispatch for the Visitor pattern
*/
virtual void accept(Visitor& visitor) = 0;
/**
* \brief Print the formatted QASM source code of the node
*
* \param os Output stream
*/
virtual std::ostream& pretty_print(std::ostream& os) const = 0;
/**
* \brief Generate a deep copy of the node
*/
virtual ASTNode* clone() const = 0;
/**
* \brief Extraction operator override
*
* Extraction is non-virtual and delegates to pretty_print
*
* \param os Output stream
* \param node Node to print
*/
friend std::ostream& operator<<(std::ostream& os, const ASTNode& node) {
return node.pretty_print(os);
}
};
} // namespace ast
} // namespace staq
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* \file ast/decl.hpp
* \brief openQASM declarations
*/
#pragma once
#include "stmt.hpp"
#include <list>
namespace staq {
namespace ast {
static const std::set<std::string_view> qelib_defs{
"u3", "u2", "u1", "cx", "id", "u0", "x", "y", "z",
"h", "s", "sdg", "t", "tdg", "rx", "ry", "rz", "cz",
"cy", "swap", "ch", "ccx", "crz", "cu1", "cu3"};
/**
* \brief Tests whether identifier is part of the standard openQASM qelib or not
*
* \param id Identifier
* \return True if \a id is part of the standard openQASM qelib, false otherwise
*/
inline bool is_std_qelib(const std::string& id) {
return qelib_defs.find(id) != qelib_defs.end();
}