Skip to content

Commit f90b5da

Browse files
authored
Expose estimate resources as dict (#3662)
* Adding an api to expose gateCounts as a dictionary * adding a doc comment for the method * Keeping track of resources when instructions are appended * Updating map to take controls into account * adding a test for control gates * reverting the functionality for count Signed-off-by: Sachin Pisal <[email protected]> * Using instructions map to expose gateCounts * initializing nControls to 0 --------- Signed-off-by: Sachin Pisal <[email protected]>
1 parent dcf700c commit f90b5da

File tree

4 files changed

+87
-2
lines changed

4 files changed

+87
-2
lines changed

python/runtime/common/py_Resources.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ This includes all gate counts.)#")
5555
},
5656
"Return a string of the raw resource counts that are stored in "
5757
"`self`.\n")
58+
.def(
59+
"to_dict", [](Resources &self) { return self.gateCounts(); },
60+
"Return a dictionary of the raw resource counts that are stored in "
61+
"`self`.\n")
5862
.def("clear", &Resources::clear, "Clear out all metadata from `self`.\n");
5963
}
6064

python/tests/backends/test_resource_counter.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,50 @@ def mykernel():
4646
assert counts.count("s") == 1
4747
assert counts.count("t") == 1
4848

49+
d = counts.to_dict()
50+
assert d["rx"] == 1
51+
assert d["ry"] == 1
52+
assert d["rz"] == 1
53+
assert d["h"] == 1
54+
assert d["x"] == 1
55+
assert d["y"] == 1
56+
assert d["z"] == 1
57+
assert d["s"] == 1
58+
assert d["t"] == 1
59+
60+
61+
def test_control_gates_resources():
62+
63+
@cudaq.kernel
64+
def mykernel():
65+
q = cudaq.qvector(3)
66+
x(q[0])
67+
x.ctrl(q[0], q[1])
68+
x.ctrl([q[0], q[1]], q[2])
69+
h(q[0])
70+
h.ctrl(q[0], q[1])
71+
72+
counts = cudaq.estimate_resources(mykernel)
73+
74+
assert counts.count_controls("x", 0) == 1
75+
assert counts.count_controls("x", 1) == 1
76+
assert counts.count_controls("x", 2) == 1
77+
78+
assert counts.count_controls("h", 0) == 1
79+
assert counts.count_controls("h", 1) == 1
80+
81+
assert counts.count() == 5
82+
83+
d = counts.to_dict()
84+
assert isinstance(d, dict)
85+
86+
assert d["x"] == 1
87+
assert d["h"] == 1
88+
89+
assert d["cx"] == 1
90+
assert d["ccx"] == 1
91+
assert d["ch"] == 1
92+
4993

5094
def test_choice_function():
5195

@@ -73,6 +117,14 @@ def choice():
73117
assert counts2.count("h") == 1
74118
assert counts2.count("x") == 1
75119

120+
d1 = counts1.to_dict()
121+
d2 = counts2.to_dict()
122+
assert isinstance(d1, dict)
123+
assert isinstance(d2, dict)
124+
assert d1["h"] == 1
125+
assert d2["h"] == 1
126+
assert d2["x"] == 1
127+
76128
cudaq.set_target("quantinuum", emulate=True)
77129
counts1 = cudaq.estimate_resources(mykernel)
78130
counts2 = cudaq.estimate_resources(mykernel, choice=choice)
@@ -81,6 +133,12 @@ def choice():
81133
assert counts2.count("h") == 1
82134
assert counts2.count("x") == 1
83135

136+
d1 = counts1.to_dict()
137+
d2 = counts2.to_dict()
138+
assert d1["h"] == 1
139+
assert d2["h"] == 1
140+
assert d2["x"] == 1
141+
84142

85143
def test_choice_function():
86144

@@ -162,11 +220,21 @@ def caller(n: int, angles: list[float]):
162220
assert counts.count("rx") == 3
163221
assert counts.count("h") == 1
164222

223+
d = counts.to_dict()
224+
assert isinstance(d, dict)
225+
assert d["rx"] == 3
226+
assert d["h"] == 1
227+
165228
cudaq.set_target("qci", emulate=True)
166229
counts = cudaq.estimate_resources(caller, 3, [4.0, 5.0, 6.0])
167230
assert counts.count("rx") == 3
168231
assert counts.count("h") == 1
169232

233+
d = counts.to_dict()
234+
assert isinstance(d, dict)
235+
assert d["rx"] == 3
236+
assert d["h"] == 1
237+
170238

171239
# leave for gdb debugging
172240
if __name__ == "__main__":

runtime/common/Resources.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void Resources::dump(std::ostream &os) const {
7777
os << "\n ";
7878
std::size_t counter = 0;
7979
for (auto &result : instructions) {
80-
std::string gatestr("c", result.first.nControls);
80+
std::string gatestr(result.first.nControls, 'c');
8181
gatestr += result.first.name;
8282
os << gatestr << " : " << result.second;
8383
bool isLast = counter == instructions.size() - 1;
@@ -96,4 +96,14 @@ void Resources::clear() {
9696
}
9797

9898
void Resources::addQubit() { numQubits++; }
99+
100+
std::unordered_map<std::string, std::size_t> Resources::gateCounts() const {
101+
std::unordered_map<std::string, std::size_t> gateCounts;
102+
for (auto &result : instructions) {
103+
std::string gatestr(result.first.nControls, 'c');
104+
gatestr += result.first.name;
105+
gateCounts[gatestr] = result.second;
106+
}
107+
return gateCounts;
108+
}
99109
} // namespace cudaq

runtime/common/Resources.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class Resources {
3939
/// @brief The number of controls
4040
std::size_t nControls;
4141

42-
Instruction(const std::string &n) : name(n) {}
42+
Instruction(const std::string &n) : name(n), nControls(0) {}
4343

4444
/// @brief The constructor
4545
Instruction(const std::string &n, const size_t c) : name(n), nControls(c) {}
@@ -82,6 +82,9 @@ class Resources {
8282
/// @brief Register the usage of an additional qubit
8383
void addQubit();
8484

85+
/// @brief Returns a dictionary mapping gate names to counts
86+
std::unordered_map<std::string, std::size_t> gateCounts() const;
87+
8588
private:
8689
/// @brief Map of Instructions in the current kernel to the
8790
/// number of times the Instruction is used.

0 commit comments

Comments
 (0)