Skip to content

Commit 2161a87

Browse files
committed
Make fixes based on copilot review
1 parent a953dc1 commit 2161a87

3 files changed

Lines changed: 103 additions & 121 deletions

File tree

src/circuit/qasm3_exporter.hpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22
#define __qiskitcpp_circuit_qasm3_exporter_hpp__
33

44
#include "circuit/quantumcircuit_def.hpp"
5-
#include <iostream>
5+
#include <algorithm>
6+
#include <cassert>
7+
#include <cstring>
8+
#include <iomanip>
9+
#include <iterator>
610
#include <set>
11+
#include <sstream>
12+
#include <string>
713

14+
15+
namespace Qiskit {
16+
namespace circuit {
817
std::string to_qasm3(circuit::QuantumCircuit &circ)
918
{
1019
auto rust_circ = circ.get_rust_circuit(true);
@@ -41,26 +50,25 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
4150
size_t pos = 0;
4251
while (pos < s.size())
4352
{
44-
char c = s[pos];
53+
const char c = s[pos];
4554
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')
4655
{
47-
size_t start = pos;
48-
pos++;
56+
const size_t start = pos++;
4957
while (pos < s.size() &&
5058
((s[pos] >= 'a' && s[pos] <= 'z') ||
5159
(s[pos] >= 'A' && s[pos] <= 'Z') ||
5260
(s[pos] >= '0' && s[pos] <= '9') || s[pos] == '_'))
5361
{
5462
pos++;
5563
}
56-
std::string token = s.substr(start, pos - start);
64+
const std::string token = s.substr(start, pos - start);
5765
if (reserved.find(token) == reserved.end())
5866
{
5967
symbol_names.insert(token);
6068
}
61-
else
62-
pos++;
69+
continue;
6370
}
71+
pos++;
6472
}
6573
}
6674
qk_circuit_instruction_clear(&inst);
@@ -349,12 +357,12 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
349357
break;
350358
case QkGate_CU1:
351359
qasm3 << "gate cu1(p0) _gate_q_0, _gate_q_1 {" << std::endl;
352-
qasm3 << " cp(p0) _gate_q_0 _gate_q_1;" << std::endl;
360+
qasm3 << " cp(p0) _gate_q_0, _gate_q_1;" << std::endl;
353361
qasm3 << "}" << std::endl;
354362
break;
355363
case QkGate_CU3:
356364
qasm3 << "gate cu3(p0, p1, p2) _gate_q_0, _gate_q_1 {" << std::endl;
357-
qasm3 << " cu(p0, p1, p2, 0) _gate_q_0 _gate_q_1;" << std::endl;
365+
qasm3 << " cu(p0, p1, p2, 0) _gate_q_0, _gate_q_1;" << std::endl;
358366
qasm3 << "}" << std::endl;
359367
break;
360368
default:
@@ -374,20 +382,22 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
374382
const std::string qreg_name = "q";
375383
qasm3 << "qubit[" << circ.num_qubits() << "] " << qreg_name << ";"
376384
<< std::endl;
377-
for (const auto &creg : circ.cregs)
385+
386+
const auto &cregs = circ.cregs();
387+
for (const auto &creg : cregs)
378388
{
379389
qasm3 << "bit[" << creg.size() << "] " << creg.name() << ";" << std::endl;
380390
}
381391

382392
auto recover_reg_data =
383-
[this](uint_t index) -> std::pair<std::string, uint_t>
393+
[&cregs](uint_t index) -> std::pair<std::string, uint_t>
384394
{
385-
auto it = std::upper_bound(circ.cregs.begin(), circ.cregs.end(), index,
395+
auto it = std::upper_bound(cregs.begin(), cregs.end(), index,
386396
[](uint_t v, const ClassicalRegister &reg)
387397
{
388398
return v < reg.base_index();
389399
});
390-
assert(it != circ.cregs.begin());
400+
assert(it != cregs.begin());
391401
it = std::prev(it);
392402
return std::make_pair(it->name(), index - it->base_index());
393403
};
@@ -398,9 +408,9 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
398408
qk_circuit_get_instruction(rust_circ.get(), i, op);
399409
if (op->num_clbits > 0)
400410
{
401-
if (op->circ.num_qubits == op->num_clbits)
411+
if (op->num_qubits == op->num_clbits)
402412
{
403-
for (uint_t j = 0; j < op->circ.num_qubits; j++)
413+
for (uint_t j = 0; j < op->num_qubits; j++)
404414
{
405415
const auto creg_data = recover_reg_data(op->clbits[j]);
406416
qasm3 << creg_data.first << "[" << creg_data.second
@@ -432,13 +442,13 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
432442
}
433443
qasm3 << ")";
434444
}
435-
if (op->circ.num_qubits > 0)
445+
if (op->num_qubits > 0)
436446
{
437447
qasm3 << " ";
438-
for (uint_t j = 0; j < op->circ.num_qubits; j++)
448+
for (uint_t j = 0; j < op->num_qubits; j++)
439449
{
440450
qasm3 << qreg_name << "[" << op->qubits[j] << "]";
441-
if (j != op->circ.num_qubits - 1)
451+
if (j != op->num_qubits - 1)
442452
qasm3 << ", ";
443453
}
444454
}
@@ -449,4 +459,7 @@ std::string to_qasm3(circuit::QuantumCircuit &circ)
449459

450460
return qasm3.str();
451461
}
452-
#endif
462+
}
463+
}
464+
465+
#endif // __qiskitcpp_circuit_qasm3_exporter_hpp__

src/circuit/quantumcircuit_impl.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,11 @@ inline void QuantumCircuit::add_pending_control_flow_op(void)
5757
}
5858

5959

60-
}
61-
}
62-
63-
inline std::string QuantumCircuit::to_qasm3(void)
60+
std::string QuantumCircuit::to_qasm3(void)
6461
{
6562
return to_qasm3(*this);
6663
}
64+
}
65+
}
6766

6867
#endif // __qiskitcpp_circuit_quantum_circuit_impl_hpp__

test/test_circuit.cpp

Lines changed: 68 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -641,111 +641,81 @@ static int test_to_qasm3(void) {
641641
return Ok;
642642
}
643643

644-
static int test_to_qasm3_multi_regs(void) {
645-
auto qreg1 = QuantumRegister(2, std::string("q1"));
646-
auto qreg2 = QuantumRegister(1, std::string("q2"));
647-
auto creg1 = ClassicalRegister(2, std::string("c1"));
648-
auto creg2 = ClassicalRegister(1, std::string("c2"));
649-
QuantumCircuit circ(std::vector<QuantumRegister>({qreg1, qreg2}),
650-
std::vector<ClassicalRegister>({creg1, creg2}));
651-
652-
circ.measure(qreg2, creg2);
653-
circ.measure(qreg1, creg1);
654-
655-
const auto actual = circ.to_qasm3();
656-
const std::string expected = "OPENQASM 3.0;\n"
657-
"include \"stdgates.inc\";\n"
658-
"qubit[3] q;\n"
659-
"bit[2] c1;\n"
660-
"bit[1] c2;\n"
661-
"c2[0] = measure q[2];\n"
662-
"c1[0] = measure q[0];\n"
663-
"c1[1] = measure q[1];\n";
664-
if (actual != expected) {
665-
std::cerr << " to_qasm3_multi_regs test : \n expected:\n"
666-
<< expected << "\n actual:\n"
667-
<< actual << std::endl;
668-
return EqualityError;
669-
}
670-
671-
return Ok;
672-
}
673-
674644
static int test_to_qasm3_single_param(void) {
675-
auto circ = QuantumCircuit(1, 0);
676-
Parameter theta("theta");
677-
circ.rx(theta, 0);
678-
679-
const auto actual = circ.to_qasm3();
680-
const std::string expected = "OPENQASM 3.0;\n"
681-
"include \"stdgates.inc\";\n"
682-
"input float[64] theta;\n"
683-
"qubit[1] q;\n"
684-
"rx(theta) q[0];\n";
685-
if (actual != expected) {
686-
std::cerr << " to_qasm3_single_param test : \n expected:\n"
687-
<< expected << "\n actual:\n"
688-
<< actual << std::endl;
689-
return EqualityError;
690-
}
691-
return Ok;
645+
auto circ = QuantumCircuit(1, 0);
646+
Parameter theta("theta");
647+
circ.rx(theta, 0);
648+
649+
const auto actual = circ.to_qasm3();
650+
const std::string expected = "OPENQASM 3.0;\n"
651+
"include \"stdgates.inc\";\n"
652+
"input float[64] theta;\n"
653+
"qubit[1] q;\n"
654+
"rx(theta) q[0];\n";
655+
if (actual != expected) {
656+
std::cerr << " to_qasm3_single_param test : \n expected:\n"
657+
<< expected << "\n actual:\n"
658+
<< actual << std::endl;
659+
return EqualityError;
660+
}
661+
return Ok;
692662
}
693663

694664
static int test_to_qasm3_multiple_params(void) {
695-
auto circ = QuantumCircuit(2, 0);
696-
Parameter alpha("alpha");
697-
Parameter beta("beta");
698-
circ.rx(alpha, 0);
699-
circ.ry(beta, 1);
700-
701-
const auto actual = circ.to_qasm3();
702-
const std::string expected = "OPENQASM 3.0;\n"
703-
"include \"stdgates.inc\";\n"
704-
"input float[64] alpha;\n"
705-
"input float[64] beta;\n"
706-
"qubit[2] q;\n"
707-
"rx(alpha) q[0];\n"
708-
"ry(beta) q[1];\n";
709-
if (actual != expected) {
710-
std::cerr << " to_qasm3_multiple_params test : \n expected:\n"
711-
<< expected << "\n actual:\n"
712-
<< actual << std::endl;
713-
return EqualityError;
714-
}
715-
return Ok;
665+
auto circ = QuantumCircuit(2, 0);
666+
Parameter alpha("alpha");
667+
Parameter beta("beta");
668+
circ.rx(alpha, 0);
669+
circ.ry(beta, 1);
670+
671+
const auto actual = circ.to_qasm3();
672+
const std::string expected = "OPENQASM 3.0;\n"
673+
"include \"stdgates.inc\";\n"
674+
"input float[64] alpha;\n"
675+
"input float[64] beta;\n"
676+
"qubit[2] q;\n"
677+
"rx(alpha) q[0];\n"
678+
"ry(beta) q[1];\n";
679+
if (actual != expected) {
680+
std::cerr << " to_qasm3_multiple_params test : \n expected:\n"
681+
<< expected << "\n actual:\n"
682+
<< actual << std::endl;
683+
return EqualityError;
684+
}
685+
return Ok;
716686
}
717687

718688
static int test_to_qasm3_expression_param(void) {
719-
auto circ = QuantumCircuit(1, 0);
720-
Parameter t("t");
721-
Parameter expr = t + Parameter(0.5);
722-
circ.rz(expr, 0);
723-
724-
const auto actual = circ.to_qasm3();
725-
// The expression "0.5 + t" (or "t + 0.5") should cause only "t" to be
726-
// declared as input, not the numeric literal.
727-
if (actual.find("input float[64] t;") == std::string::npos) {
728-
std::cerr
729-
<< " to_qasm3_expression_param test : missing 'input float[64] t;'\n"
730-
<< " actual:\n"
731-
<< actual << std::endl;
732-
return EqualityError;
733-
}
734-
735-
size_t count = 0;
736-
size_t pos = 0;
737-
while ((pos = actual.find("input float[64]", pos)) != std::string::npos) {
738-
count++;
739-
pos += 15;
740-
}
741-
if (count != 1) {
742-
std::cerr << " to_qasm3_expression_param test : expected 1 input "
743-
"declaration, got "
744-
<< count << "\n actual:\n"
745-
<< actual << std::endl;
746-
return EqualityError;
747-
}
748-
return Ok;
689+
auto circ = QuantumCircuit(1, 0);
690+
Parameter t("t");
691+
Parameter expr = t + Parameter(0.5);
692+
circ.rz(expr, 0);
693+
694+
const auto actual = circ.to_qasm3();
695+
// The expression "0.5 + t" (or "t + 0.5") should cause only "t" to be
696+
// declared as input, not the numeric literal.
697+
if (actual.find("input float[64] t;") == std::string::npos) {
698+
std::cerr
699+
<< " to_qasm3_expression_param test : missing 'input float[64] t;'\n"
700+
<< " actual:\n"
701+
<< actual << std::endl;
702+
return EqualityError;
703+
}
704+
705+
size_t count = 0;
706+
size_t pos = 0;
707+
while ((pos = actual.find("input float[64]", pos)) != std::string::npos) {
708+
count++;
709+
pos += 15;
710+
}
711+
if (count != 1) {
712+
std::cerr << " to_qasm3_expression_param test : expected 1 input "
713+
"declaration, got "
714+
<< count << "\n actual:\n"
715+
<< actual << std::endl;
716+
return EqualityError;
717+
}
718+
return Ok;
749719
}
750720

751721
#if defined(_WIN32)

0 commit comments

Comments
 (0)