Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions src/circuit/quantumcircuit_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1506,16 +1506,29 @@ std::string QuantumCircuit::to_qasm3(void)
}
qk_opcounts_clear(&opcounts);

// registers
std::string creg_name = "c";
std::string qreg_name = "q";
qasm3 << "bit[" << num_clbits() << "] " << creg_name << ";" << std::endl;
qasm3 << "qubit[" << num_qubits() << "] " << qreg_name << ";" << std::endl;

// save ops
uint_t nops;
nops = qk_circuit_num_instructions(rust_circuit_.get());

// Declare registers
// After transpilation, qubit registers will be mapped to physical registers,
// so we need to combined them in a single quantum register "q";
const std::string qreg_name = "q";
qasm3 << "qubit[" << num_qubits() << "] " << qreg_name << ";" << std::endl;
for(const auto& creg : cregs_)
{
qasm3 << "bit[" << creg.size() << "] " << creg.name() << ";" << std::endl;
}

auto recover_reg_data = [this](uint_t index) -> std::pair<std::string, uint_t>
{
auto it = std::upper_bound(cregs_.begin(), cregs_.end(), index,
[](uint_t v, const ClassicalRegister& reg) { return v < reg.base_index(); });
assert(it != cregs_.begin());
it = std::prev(it);
return std::make_pair(it->name(), index - it->base_index());
};

for (uint_t i = 0; i < nops; i++)
{
QkCircuitInstruction *op = new QkCircuitInstruction;
Expand All @@ -1526,7 +1539,8 @@ std::string QuantumCircuit::to_qasm3(void)
{
for (uint_t j = 0; j < op->num_qubits; j++)
{
qasm3 << creg_name << "[" << op->clbits[j] << "] = " << op->name << " " << qreg_name << "[" << op->qubits[j] << "];" << std::endl;
const auto creg_data = recover_reg_data(op->clbits[j]);
qasm3 << creg_data.first << "[" << creg_data.second << "] = " << op->name << " " << qreg_name << "[" << op->qubits[j] << "];" << std::endl;
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/circuit/register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class Register

/// @brief Return the size of this register
/// @return the size of this register
uint_t size(void) { return size_; }
uint_t size(void) const { return size_; }

/// @brief Return the name of this register
/// @return the name of this register
Expand All @@ -157,6 +157,10 @@ class Register
base_index_ = base;
}

/// @brief Return the base index of this register
/// @return the base index of this register
uint_t base_index() const { return base_index_; }

Bit &operator[](const uint_t i) { return bits_[i]; }

protected:
Expand Down
30 changes: 30 additions & 0 deletions test/test_circuit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,13 +614,43 @@ static int test_compose(void) {
return Ok;
}

static int test_to_qasm3_multi_regs(void) {
auto qreg1 = QuantumRegister(2, std::string("q1"));
auto qreg2 = QuantumRegister(1, std::string("q2"));
auto creg1 = ClassicalRegister(2, std::string("c1"));
auto creg2 = ClassicalRegister(1, std::string("c2"));
QuantumCircuit circ(std::vector<QuantumRegister>({qreg1, qreg2}), std::vector<ClassicalRegister>({creg1, creg2}));

circ.measure(qreg2, creg2);
circ.measure(qreg1, creg1);

const auto actual = circ.to_qasm3();
const std::string expected =
"OPENQASM 3.0;\n"
"include \"stdgates.inc\";\n"
"qubit[3] q;\n"
"bit[2] c1;\n"
"bit[1] c2;\n"
"c2[0] = measure q[2];\n"
"c1[0] = measure q[0];\n"
"c1[1] = measure q[1];\n";
if (actual != expected) {
std::cerr << " to_qasm3_multi_regs test : \n expected:\n" << expected
<< "\n actual:\n" << actual << std::endl;
return EqualityError;
}

return Ok;
}


extern "C" int test_circuit(void) {
int num_failed = 0;
num_failed += RUN_TEST(test_standard_gates);
num_failed += RUN_TEST(test_measure);
num_failed += RUN_TEST(test_append);
num_failed += RUN_TEST(test_compose);
num_failed += RUN_TEST(test_to_qasm3_multi_regs);

std::cerr << "=== Number of failed subtests: " << num_failed << std::endl;
return num_failed;
Expand Down