Skip to content

Commit 0e2463d

Browse files
authored
Merge branch 'main' into feature/add-qilimanjaro-target
2 parents 1a45098 + 1c8c796 commit 0e2463d

File tree

21 files changed

+341
-205
lines changed

21 files changed

+341
-205
lines changed

include/cudaq/Optimizer/CodeGen/QIRAttributeNames.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static constexpr const char BackwardsBranchingFlagName[] =
4747
"backwards_branching";
4848
} // namespace qir0_1
4949

50-
namespace qir0_2 {
50+
namespace qir1_0 {
5151
static constexpr const char RequiredQubitsAttrName[] = "required_num_qubits";
5252
static constexpr const char RequiredResultsAttrName[] = "required_num_results";
5353

@@ -60,6 +60,6 @@ static constexpr const char MultipleTargetBranchingFlagName[] =
6060
"multiple_target_branching";
6161
static constexpr const char MultipleReturnPointsFlagName[] =
6262
"multiple_return_points";
63-
} // namespace qir0_2
63+
} // namespace qir1_0
6464

6565
} // namespace cudaq::opt

include/cudaq/Optimizer/CodeGen/QIRFunctionNames.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static constexpr const char ReadResultBody[] =
3131
"__quantum__qis__read_result__body";
3232
}
3333

34-
namespace qir0_2 {
34+
namespace qir1_0 {
3535
static constexpr const char ReadResult[] = "__quantum__rt__read_result";
3636
}
3737

lib/Optimizer/CodeGen/ConvertToQIRAPI.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ struct DiscriminateOpRewrite
587587
};
588588

589589
// Supported QIR versions.
590-
enum struct QirVersion { version_0_1, version_0_2 };
590+
enum struct QirVersion { version_0_1, version_1_0 };
591591

592592
template <typename M>
593593
struct DiscriminateOpToCallRewrite
@@ -598,9 +598,9 @@ struct DiscriminateOpToCallRewrite
598598
matchAndRewrite(quake::DiscriminateOp disc, OpAdaptor adaptor,
599599
ConversionPatternRewriter &rewriter) const override {
600600
if constexpr (M::discriminateToClassical) {
601-
if constexpr (M::qirVersion == QirVersion::version_0_2) {
601+
if constexpr (M::qirVersion == QirVersion::version_1_0) {
602602
rewriter.replaceOpWithNewOp<func::CallOp>(
603-
disc, rewriter.getI1Type(), cudaq::opt::qir0_2::ReadResult,
603+
disc, rewriter.getI1Type(), cudaq::opt::qir1_0::ReadResult,
604604
adaptor.getOperands());
605605
} else {
606606
rewriter.replaceOpWithNewOp<func::CallOp>(
@@ -2049,14 +2049,14 @@ struct QuakeToQIRAPIPass
20492049
else
20502050
processOperation<FullQIR</*opaquePtr=*/false>>(typeConverter);
20512051
} else if (apiField[0] == "base-profile") {
2052-
if (apiField.size() > 1 && apiField[1] == "0.2") {
2052+
if (apiField.size() > 1 && apiField[1] == "1.0") {
20532053
if (opaquePtr)
20542054
processOperation<
2055-
BaseProfileQIR</*opaquePtr=*/true, QirVersion::version_0_2>>(
2055+
BaseProfileQIR</*opaquePtr=*/true, QirVersion::version_1_0>>(
20562056
typeConverter);
20572057
else
20582058
processOperation<
2059-
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
2059+
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_1_0>>(
20602060
typeConverter);
20612061
} else {
20622062
if (opaquePtr)
@@ -2069,14 +2069,14 @@ struct QuakeToQIRAPIPass
20692069
typeConverter);
20702070
}
20712071
} else if (apiField[0] == "adaptive-profile") {
2072-
if (apiField.size() > 1 && apiField[1] == "0.2") {
2072+
if (apiField.size() > 1 && apiField[1] == "1.0") {
20732073
if (opaquePtr)
20742074
processOperation<
2075-
AdaptiveProfileQIR</*opaquePtr=*/true, QirVersion::version_0_2>>(
2075+
AdaptiveProfileQIR</*opaquePtr=*/true, QirVersion::version_1_0>>(
20762076
typeConverter);
20772077
else
20782078
processOperation<
2079-
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
2079+
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_1_0>>(
20802080
typeConverter);
20812081
} else {
20822082
if (opaquePtr)
@@ -2265,14 +2265,14 @@ struct QuakeToQIRAPIPrepPass
22652265
}
22662266

22672267
static StringRef getRequiredQubitsAttrName(StringRef version) {
2268-
if (version == "0.2")
2269-
return cudaq::opt::qir0_2::RequiredQubitsAttrName;
2268+
if (version == "1.0")
2269+
return cudaq::opt::qir1_0::RequiredQubitsAttrName;
22702270
return cudaq::opt::qir0_1::RequiredQubitsAttrName;
22712271
}
22722272

22732273
static StringRef getRequiredResultsAttrName(StringRef version) {
2274-
if (version == "0.2")
2275-
return cudaq::opt::qir0_2::RequiredResultsAttrName;
2274+
if (version == "1.0")
2275+
return cudaq::opt::qir1_0::RequiredResultsAttrName;
22762276
return cudaq::opt::qir0_1::RequiredResultsAttrName;
22772277
}
22782278

python/runtime/cudaq/algorithms/py_translate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ path, i.e., the trace, of the provided `kernel`.
6666
Args:
6767
format (str): format to translate to, <name[:version]>.
6868
Available format names: `qir`, `qir-full`, `qir-base`, `qir-adaptive`,
69-
`openqasm2`. QIR versions: `0.1` and `0.2`.
69+
`openqasm2`. QIR versions: `0.1` and `1.0`.
7070
kernel (:class:`Kernel`): The :class:`Kernel` to translate.
7171
*arguments (Optional[Any]): The concrete values to evaluate the kernel
7272
function at. Leave empty if the kernel doesn't accept any arguments.

python/tests/backends/test_QCI.py

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
from multiprocessing import Process
1111

1212
import cudaq
13-
from cudaq import spin
13+
import numpy as np
1414
import pytest
15+
from cudaq import spin
1516
from network_utils import check_server_connection
1617

1718
try:
@@ -64,7 +65,6 @@ def test_sample():
6465
kernel.h(qubits[0])
6566
kernel.cx(qubits[0], qubits[1])
6667
kernel.mz(qubits)
67-
print(kernel)
6868

6969
# Run sample synchronously
7070
counts = cudaq.sample(kernel)
@@ -80,7 +80,6 @@ def test_sample():
8080
assert "11" in counts
8181

8282
future = cudaq.sample_async(kernel)
83-
print(future)
8483

8584
# Persist the future to a file
8685
futureAsString = str(future)
@@ -105,7 +104,7 @@ def ansatz(theta: float):
105104
0) * spin.y(1) + .21829 * spin.z(0) - 6.125 * spin.z(1)
106105

107106
# Run the observe task on synchronously
108-
res = cudaq.observe(ansatz, hamiltonian, .59, shots_count=100)
107+
res = cudaq.observe(ansatz, hamiltonian, .59, shots_count=200)
109108
assert assert_close(res.expectation())
110109

111110
# Launch it asynchronously, enters the job into the queue
@@ -117,7 +116,6 @@ def ansatz(theta: float):
117116
# Launch the job async, job goes in the queue, and
118117
# we're free to dump the future to file
119118
future = cudaq.observe_async(ansatz, hamiltonian, .59, shots_count=100)
120-
print(future)
121119
futureAsString = str(future)
122120

123121
# Later you can come back and read it in
@@ -128,6 +126,129 @@ def ansatz(theta: float):
128126
assert assert_close(res.expectation())
129127

130128

129+
def test_u3_decomposition():
130+
131+
@cudaq.kernel
132+
def kernel():
133+
qubit = cudaq.qubit()
134+
u3(0.0, np.pi / 2, np.pi, qubit)
135+
mz(qubit)
136+
137+
# Test here is that this runs without error
138+
cudaq.sample(kernel, shots_count=10)
139+
140+
141+
def test_u3_ctrl_decomposition():
142+
143+
@cudaq.kernel
144+
def kernel():
145+
control = cudaq.qubit()
146+
target = cudaq.qubit()
147+
u3.ctrl(0.0, np.pi / 2, np.pi, control, target)
148+
mz(control)
149+
mz(target)
150+
151+
# Test here is that this runs without error
152+
cudaq.sample(kernel, shots_count=10)
153+
154+
155+
def test_state_preparation():
156+
157+
@cudaq.kernel
158+
def kernel(vec: list[complex]):
159+
qubits = cudaq.qvector(vec)
160+
mz(qubits)
161+
162+
state = [1. / np.sqrt(2.), 1. / np.sqrt(2.), 0., 0.]
163+
counts = cudaq.sample(kernel, state)
164+
assert '00' in counts
165+
assert '10' in counts
166+
assert not '01' in counts
167+
assert not '11' in counts
168+
169+
170+
def test_state_synthesis_from_simulator():
171+
172+
@cudaq.kernel
173+
def kernel(state: cudaq.State):
174+
qubits = cudaq.qvector(state)
175+
mz(qubits)
176+
177+
state = cudaq.State.from_data(
178+
np.array([1. / np.sqrt(2.), 1. / np.sqrt(2.), 0., 0.], dtype=complex))
179+
180+
counts = cudaq.sample(kernel, state)
181+
assert "00" in counts
182+
assert "10" in counts
183+
assert len(counts) == 2
184+
185+
synthesized = cudaq.synthesize(kernel, state)
186+
counts = cudaq.sample(synthesized)
187+
assert '00' in counts
188+
assert '10' in counts
189+
assert len(counts) == 2
190+
191+
192+
def test_state_synthesis():
193+
194+
@cudaq.kernel
195+
def init(n: int):
196+
q = cudaq.qvector(n)
197+
x(q[0])
198+
199+
@cudaq.kernel
200+
def kernel(s: cudaq.State):
201+
q = cudaq.qvector(s)
202+
x(q[1])
203+
mz(q)
204+
205+
s = cudaq.get_state(init, 2)
206+
counts = cudaq.sample(kernel, s)
207+
assert '11' in counts
208+
assert len(counts) == 1
209+
210+
211+
def test_exp_pauli():
212+
213+
@cudaq.kernel
214+
def test():
215+
q = cudaq.qvector(2)
216+
exp_pauli(1.0, q, "XX")
217+
mz(q)
218+
219+
counts = cudaq.sample(test)
220+
assert '00' in counts
221+
assert '11' in counts
222+
assert not '01' in counts
223+
assert not '10' in counts
224+
225+
226+
def test_run():
227+
228+
@cudaq.kernel
229+
def simple(numQubits: int) -> int:
230+
qubits = cudaq.qvector(numQubits)
231+
h(qubits.front())
232+
for i, qubit in enumerate(qubits.front(numQubits - 1)):
233+
x.ctrl(qubit, qubits[i + 1])
234+
result = 0
235+
for i in range(numQubits):
236+
if mz(qubits[i]):
237+
result += 1
238+
return result
239+
240+
shots = 100
241+
qubitCount = 4
242+
results = cudaq.run(simple, qubitCount, shots_count=shots)
243+
assert len(results) == shots
244+
non_zero_count = 0
245+
for result in results:
246+
assert result == 0 or result == qubitCount # 00..0 or 1...11
247+
if result == qubitCount:
248+
non_zero_count += 1
249+
assert non_zero_count > 0
250+
251+
131252
# leave for gdb debugging
132253
if __name__ == "__main__":
133254
loc = os.path.abspath(__file__)

python/tests/mlir/qir_profile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def my_kernel():
3333
x(q)
3434
mz(q)
3535

36-
# This device requires qir:0.2
36+
# This device requires qir:1.0
3737
cudaq.set_target('quantinuum', emulate=True, machine='Helios-1E')
3838
result = cudaq.sample(my_kernel)
3939

python/tests/parallel/test_mqpu.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
# the terms of the Apache License 2.0 which accompanies this distribution. #
77
# ============================================================================ #
88

9-
import cudaq, os, pytest, random, timeit
10-
from cudaq import spin
9+
import os
10+
import random
11+
import time
12+
import timeit
13+
14+
import cudaq
1115
import numpy as np
16+
import pytest
17+
from cudaq import spin
1218

1319
skipIfNoMQPU = pytest.mark.skipif(
1420
not (cudaq.num_available_gpus() > 0 and cudaq.has_target('nvidia-mqpu')),
@@ -18,6 +24,11 @@
1824
@pytest.fixture(autouse=True)
1925
def do_something():
2026
cudaq.set_target('nvidia-mqpu')
27+
try:
28+
assert cudaq.get_target().num_qpus(
29+
) > 0, "No QPUs available after target set"
30+
except Exception as e:
31+
pytest.skip(f"MQPU setup failed: {str(e)}")
2132
yield
2233
cudaq.__clearKernelRegistries()
2334
cudaq.reset_target()
@@ -155,12 +166,6 @@ def parameterized_kernel(n: int, layers: int, params: list[float],
155166

156167

157168
def check_accuracy(entity):
158-
target = cudaq.get_target()
159-
numQpus = target.num_qpus()
160-
if numQpus == 0:
161-
pytest.skip("No QPUs available for target, skipping test")
162-
else:
163-
print(f"Target: {target}, NumQPUs: {numQpus}")
164169
# Define its spin Hamiltonian.
165170
hamiltonian = 5.907 - 2.1433 * spin.x(0) * spin.x(1) - 2.1433 * spin.y(
166171
0) * spin.y(1) + .21829 * spin.z(0) - 6.125 * spin.z(1)

runtime/common/CodeGenConfig.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ std::vector<std::string> splitString(const std::string &s,
2828

2929
/// @brief Helper to parse `codegen` translation, with optional feature
3030
/// annotation.
31-
// e.g., "qir-adaptive:0.2:int_computations,float_computations"
31+
// e.g., "qir-adaptive:1.0:int_computations,float_computations"
3232
static std::tuple<std::string, std::string, std::vector<std::string>>
3333
parseCodeGenTranslationString(const std::string &settingStr) {
3434
auto transportFields = splitString(settingStr, ':');
@@ -100,10 +100,10 @@ cudaq::parseCodeGenTranslation(const std::string &codegenTranslation) {
100100
config.version = QirVersion::version_0_1;
101101
config.qir_major_version = 0;
102102
config.qir_minor_version = 1;
103-
} else if (codeGenVersion == "0.2") {
104-
config.version = QirVersion::version_0_2;
105-
config.qir_major_version = 0;
106-
config.qir_minor_version = 2;
103+
} else if (codeGenVersion == "1.0") {
104+
config.version = QirVersion::version_1_0;
105+
config.qir_major_version = 1;
106+
config.qir_minor_version = 0;
107107
} else {
108108
throw std::runtime_error(
109109
fmt::format("Unsupported QIR version '{}', codegen setting: {}",

runtime/common/CodeGenConfig.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
namespace cudaq {
1717

18-
enum struct QirVersion { version_0_1, version_0_2 };
18+
enum struct QirVersion { version_0_1, version_1_0 };
1919

2020
/// @brief `Codegen` configuration.
2121
/// Note: it is currently flattened to contain all possible options
@@ -52,7 +52,7 @@ struct CodeGenConfig {
5252

5353
/// @brief Helper to parse `codegen` translation, with optional feature
5454
/// annotation.
55-
/// e.g., `qir-adaptive:0.2:int_computations,float_computations`.
55+
/// e.g., `qir-adaptive:1.0:int_computations,float_computations`.
5656
/// Handles errors and returns structured configuration.
5757
CodeGenConfig parseCodeGenTranslation(const std::string &codegenTranslation);
5858
} // namespace cudaq

runtime/common/RecordLogParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void cudaq::RecordLogParser::handleMetadata(
8383
if (entries.size() < 2 || entries.size() > 3)
8484
cudaq::info("Unexpected METADATA record: {}. Ignored.\n", entries);
8585
if (entries.size() == 3) {
86-
if (entries[1] == cudaq::opt::qir0_2::RequiredResultsAttrName ||
86+
if (entries[1] == cudaq::opt::qir1_0::RequiredResultsAttrName ||
8787
entries[1] == cudaq::opt::qir0_1::RequiredResultsAttrName) {
8888
metadata[ResultCountMetadataName] = entries[2];
8989
} else {

0 commit comments

Comments
 (0)