Skip to content

Commit

Permalink
[rt] Fix #1215
Browse files Browse the repository at this point in the history
  • Loading branch information
boschmitt committed Feb 13, 2024
1 parent d2f6bbc commit 877273b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
17 changes: 16 additions & 1 deletion runtime/cudaq/qis/managers/BasicExecutionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,22 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
for (auto &t : targets)
mutable_targets.push_back(t);

if (isAdjoint || !adjointQueueStack.empty()) {
// We need to check if we need take the adjoint of the operation. To do this
// we use a logical XOR between `isAdjoint` and whether the size of
// `adjointQueueStack` is even. The size of `adjointQueueStack` corresponds
// to the number of nested `cudaq::adjoint` calls. If the size is even, then
// we need to change the operation when `isAdjoint` is true. If the size is
// odd, then we need to change the operation when `isAdjoint` is false.
// (Adjoint modifiers cancel each other, e.g, `adj adj r1` is `r1`.)
//
// The cases:
// * not-adjoint, even number of `cudaq::adjoint` => _no_ need to change op
// * not-adjoint, odd number of `cudaq::adjoint` => change op
// * adjoint, even number of `cudaq::adjoint` => change op
// * adjoint, odd number `cudaq::adjoint` => _no_ need to change op
//
// N.B: the `!!` is to force the result into a boolean value.
if (isAdjoint != !!(adjointQueueStack.size() % 2)) {
for (std::size_t i = 0; i < params.size(); i++)
mutable_params[i] = -1.0 * params[i];
if (gateName == "t")
Expand Down
36 changes: 36 additions & 0 deletions unittests/integration/adjoint_tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,39 @@ CUDAQ_TEST(AdjointTester, checkNestedAdjoint) {
// ctrl ry pi / 4 1 2
// }
}

// From issue: https://github.com/NVIDIA/cuda-quantum/issues/1215

__qpu__ void foo(cudaq::qubit &q) { rz<cudaq::adj>(M_PI_2, q); }

__qpu__ void bar() {
cudaq::qubit q;
rz<cudaq::adj>(M_PI_2, q);
cudaq::adjoint(foo, q);
}

CUDAQ_TEST(AdjointTester, checkEvenAdjointNesting) {
auto result = cudaq::get_state(bar);
auto amplitudes = result.get_data();
std::array<std::complex<double>, 2> expected = {1., 0};
EXPECT_EQ(expected[0], amplitudes[0]);
EXPECT_EQ(expected[1], amplitudes[1]);
}

__qpu__ void zaz(cudaq::qubit &q) { rz<cudaq::adj>(M_PI_2, q); }

__qpu__ void foo_2(cudaq::qubit &q) { cudaq::adjoint(zaz, q); }

__qpu__ void bar_2() {
cudaq::qubit q;
rz(M_PI_2, q);
cudaq::adjoint(foo_2, q);
}

CUDAQ_TEST(AdjointTester, checkOddAdjointNesting) {
auto result = cudaq::get_state(bar_2);
auto amplitudes = result.get_data();
std::array<std::complex<double>, 2> expected = {1., 0};
EXPECT_EQ(expected[0], amplitudes[0]);
EXPECT_EQ(expected[1], amplitudes[1]);
}

0 comments on commit 877273b

Please sign in to comment.