qir-alliance / qcor

C++ compiler for heterogeneous quantum-classical computing built on Clang and XACC
http://docs.aide-qc.org
MIT License
97 stars 39 forks source link

Pass ancilla buffer to XACC even if user passes multiple qregs #259

Open ausbin opened 2 years ago

ausbin commented 2 years ago

This is an attempt to address the Quantum++ backend receiving out-of-range qubit indices in some cases. For example, due to using a different code path, this code works (thanks to Akihiro for both examples):

#include <qcor_arithmetic>

__qpu__ void CUa(qreg x, int a, int N) {
    // c = |1>
    qreg c = qalloc(1);
    X(c[0]);
    // x = |3>
    X(x[0]);
    X(x[1]);
    mul_integer_mod_in_place::ctrl(c, x, a, N);
    Measure(x);
}

int main() {
    set_verbose(true);
    int a = 1;
    int N = 2;
    set_shots(2);
    auto x = qalloc(2);
    CUa(x, a, N);
    x.print();
}

Yet this code throws a runtime error:

#include <qcor_arithmetic>

__qpu__ void CUa(qreg x, qreg c, int a, int N) {
    // c = |1>
    X(c[0]);
    // x = |3>
    X(x[0]);
    X(x[1]);
    mul_integer_mod_in_place::ctrl(c, x, a, N);
    Measure(x);
}

int main() {
    set_verbose(true);
    int a = 1;
    int N = 2;
    set_shots(2);
    auto x = qalloc(2);
    auto c = qalloc(1);
    CUa(x, c, a, N);
    x.print();
}

Specifically, the error was:

terminate called after throwing an instance of 'qpp::exception::MatrixMismatchSubsys'
  what():  In qpp::apply(): Matrix mismatch subsystems!

Or with XACC built with debug mode, the following assertion is tripped beforehand:

.../xacc/quantum/plugins/qpp/accelerator/QppVisitor.cpp:96: qpp::idx xacc::quantum::QppVisitor::xaccIdxToQppIdx(size_t) const: Assertion `in_idx < m_buffer->size()' failed.

With this change, this issue no longer occurs because the ancilla buffer is passed for xacc::internal_compiler::execute(). Before, xacc::internal_compiler::execute() noticed that some instructions were referencing an AcceleratorBuffer aux_temp_buffer not in the list of buffers passed to it and tried to recreate one, but that apparently failed to prevent some misbehavior in this case.

Testing

Ran those two examples above, both of which worked. Also ran the unit tests via ctest, and no new tests failed compared to master