Skip to content

Commit

Permalink
implement applyExpPauli on CircuitSimulatorBase
Browse files Browse the repository at this point in the history
Signed-off-by: Alex McCaskey <[email protected]>
  • Loading branch information
amccaskey committed Sep 27, 2023
1 parent fcd9e83 commit 54bb8af
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 45 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/python_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ jobs:
image: wheel_validation:local
shell: bash
run: |
apt-get update && apt-get install -y gdb
gdb -ex r -ex bt --args python${{ inputs.python_version }} -m pytest -v -s /tmp/tests/ \
python${{ inputs.python_version }} -m pytest -v -s /tmp/tests/ \
--ignore python/tests/backends
pytest_status=$?
if [ ! $pytest_status -eq 0 ]; then
Expand Down
44 changes: 42 additions & 2 deletions runtime/nvqir/CircuitSimulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ class CircuitSimulator {
}

/// @brief Apply exp(-i theta PauliTensorProd) to the underlying state.
/// This can be further extended by subclasses that can implement this
/// in a more performant fashion.
/// This must be provided by subclasses.
virtual void applyExpPauli(double theta,
const std::vector<std::size_t> &qubitIds,
const cudaq::spin_op &op) = 0;
Expand Down Expand Up @@ -628,6 +627,47 @@ class CircuitSimulatorBase : public CircuitSimulator {
/// @brief The destructor
virtual ~CircuitSimulatorBase() = default;

void applyExpPauli(double theta, const std::vector<std::size_t> &qubitIds,
const cudaq::spin_op &op) override {
cudaq::info(" [decomposing] exp_pauli({}, {})", theta, op.to_string(false));
std::vector<std::size_t> qubitSupport;
std::vector<std::function<void(bool)>> basisChange;
op.for_each_pauli([&](cudaq::pauli type, std::size_t qubitIdx) {
if (type != cudaq::pauli::I)
qubitSupport.push_back(qubitIds[qubitIdx]);

if (type == cudaq::pauli::Y)
basisChange.emplace_back([&, qubitIdx](bool reverse) {
rx(!reverse ? M_PI_2 : -M_PI_2, qubitIds[qubitIdx]);
});
else if (type == cudaq::pauli::X)
basisChange.emplace_back(
[&, qubitIdx](bool) { h(qubitIds[qubitIdx]); });
});

if (!basisChange.empty())
for (auto &basis : basisChange)
basis(false);

std::vector<std::pair<std::size_t, std::size_t>> toReverse;
for (std::size_t i = 0; i < qubitSupport.size() - 1; i++) {
x({qubitSupport[i]}, qubitSupport[i + 1]);
toReverse.emplace_back(qubitSupport[i], qubitSupport[i + 1]);
}

rz(theta, qubitSupport.back());

std::reverse(toReverse.begin(), toReverse.end());
for (auto &[i, j] : toReverse)
x({i}, j);

if (!basisChange.empty()) {
std::reverse(basisChange.begin(), basisChange.end());
for (auto &basis : basisChange)
basis(true);
}
}

/// @brief Set the current noise model to consider when
/// simulating the state. This should be overridden by
/// simulation strategies that support noise modeling.
Expand Down
41 changes: 0 additions & 41 deletions runtime/nvqir/qpp/QppCircuitSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,47 +272,6 @@ class QppCircuitSimulator : public nvqir::CircuitSimulatorBase<double> {
return counts;
}

void applyExpPauli(double theta, const std::vector<std::size_t> &qubitIds,
const cudaq::spin_op &op) override {
cudaq::info(" [decomposing] exp_pauli({}, {})", theta, op.to_string(false));
std::vector<std::size_t> qubitSupport;
std::vector<std::function<void(bool)>> basisChange;
op.for_each_pauli([&](cudaq::pauli type, std::size_t qubitIdx) {
if (type != cudaq::pauli::I)
qubitSupport.push_back(qubitIds[qubitIdx]);

if (type == cudaq::pauli::Y)
basisChange.emplace_back([&, qubitIdx](bool reverse) {
rx(!reverse ? M_PI_2 : -M_PI_2, qubitIds[qubitIdx]);
});
else if (type == cudaq::pauli::X)
basisChange.emplace_back(
[&, qubitIdx](bool) { h(qubitIds[qubitIdx]); });
});

if (!basisChange.empty())
for (auto &basis : basisChange)
basis(false);

std::vector<std::pair<std::size_t, std::size_t>> toReverse;
for (std::size_t i = 0; i < qubitSupport.size() - 1; i++) {
x({qubitSupport[i]}, qubitSupport[i + 1]);
toReverse.emplace_back(qubitSupport[i], qubitSupport[i + 1]);
}

rz(theta, qubitSupport.back());

std::reverse(toReverse.begin(), toReverse.end());
for (auto &[i, j] : toReverse)
x({i}, j);

if (!basisChange.empty()) {
std::reverse(basisChange.begin(), basisChange.end());
for (auto &basis : basisChange)
basis(true);
}
}

cudaq::State getStateData() override {
flushGateQueue();
// There has to be at least one copy
Expand Down

0 comments on commit 54bb8af

Please sign in to comment.