Commit 0b28cbc1 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding exp-val-z calc (taken from qpp) to aer statevector mode. updating...


adding exp-val-z calc (taken from qpp) to aer statevector mode. updating internal_compiler setAccelerator to parse NAME:BACKEND[KV_OPTS] string, useful for qcor command line
Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 09f7479a
Pipeline #108456 passed with stage
in 70 minutes and 11 seconds
......@@ -2,7 +2,7 @@ import xacc
# Get access to the desired QPU and
# allocate some qubits to run on
qpu = xacc.getAccelerator('tnqvm', {'vqe-mode': True})
qpu = xacc.getAccelerator('aer', {'sim-type':'statevector'})
buffer = xacc.qalloc(4)
geom = '''
......
......@@ -98,6 +98,29 @@ void AerAccelerator::initialize(const HeterogeneousMap &params) {
std::cout << "NoiseModelJson:\n" << noise_model.dump(4) << "\n";
}
}
double AerAccelerator::calcExpectationValueZ(
const std::vector<std::pair<double, double>> &in_stateVec,
const std::vector<std::size_t> &in_bits) {
const auto hasEvenParity =
[](size_t x, const std::vector<size_t> &in_qubitIndices) -> bool {
size_t count = 0;
for (const auto &bitIdx : in_qubitIndices) {
if (x & (1ULL << bitIdx)) {
count++;
}
}
return (count % 2) == 0;
};
double result = 0.0;
for (uint64_t i = 0; i < in_stateVec.size(); ++i) {
result += (hasEvenParity(i, in_bits) ? 1.0 : -1.0) *
std::norm(std::complex<double>(in_stateVec[i].first,
in_stateVec[i].second));
}
return result;
}
void AerAccelerator::execute(
std::shared_ptr<AcceleratorBuffer> buffer,
......@@ -137,11 +160,14 @@ void AerAccelerator::execute(
// remove all measures, don't need them
auto tmp = xacc::ir::asComposite(program->clone());
tmp->clear();
std::vector<std::size_t> measured_bits;
InstructionIterator iter(program);
while (iter.hasNext()) {
auto next = iter.next();
if (!next->isComposite() && next->name() != "Measure") {
tmp->addInstruction(next);
} else if (next->name() == "Measure") {
measured_bits.push_back(next->bits()[0]);
}
}
auto qobj_str = xacc_to_qobj->translate(tmp);
......@@ -159,26 +185,8 @@ void AerAccelerator::execute(
buffer->addExtraInfo("state", state_vector);
// std::cout << "SV measure:\n";
// for (auto& [k,v] : counts) std::cout << k << " : " << v << "\n";
// const auto hasEvenParity =
// [](size_t x, const std::vector<size_t> &in_qubitIndices) -> bool {
// size_t count = 0;
// for (const auto &bitIdx : in_qubitIndices) {
// if (x & (1ULL << bitIdx)) {
// count++;
// }
// }
// return (count % 2) == 0;
// };
// double result = 0.0;
// for (uint64_t i = 0; i < m_stateVec.size(); ++i) {
// result += (hasEvenParity(i, m_measureBits) ? 1.0 : -1.0) *
// std::norm(std::complex<double>(state_vector[i][0], state_vector[i][1]));
// }
// buffer->addExtraInfo("exp-val-z", result);
auto exp_val = calcExpectationValueZ(state_vector, measured_bits);
buffer->addExtraInfo("exp-val-z", exp_val);
}
}
......
......@@ -39,6 +39,10 @@ public:
compositeInstructions) override;
private:
static double calcExpectationValueZ(
const std::vector<std::pair<double, double>> &in_stateVec,
const std::vector<std::size_t> &in_bits);
std::shared_ptr<Compiler> xacc_to_qobj;
int m_shots = 1024;
std::string m_simtype = "qasm";
......
......@@ -13,6 +13,7 @@
#include "xacc.hpp"
#include <gtest/gtest.h>
#include "xacc_observable.hpp"
TEST(AerAcceleratorTester, checkSimple) {
auto accelerator =
......@@ -40,33 +41,105 @@ TEST(AerAcceleratorTester, checkSimple) {
buffer->print(std::cout);
}
TEST(AerAcceleratorTester, checkNoise) {
// CI test don't have access to IBM, turn this on if you want to run
// auto accelerator =
// xacc::getAccelerator("aer:ibmq_vigo", {std::make_pair("shots", 100)});
// auto xasmCompiler = xacc::getCompiler("xasm");
// auto ir = xasmCompiler->compile(R"(__qpu__ void bell2(qbit q) {
// H(q[0]);
// CX(q[0], q[1]);
// Measure(q[0]);
// Measure(q[1]);
// })",
// accelerator);
TEST(AerAcceleratorTester, checkDeuteron) {
auto accelerator =
xacc::getAccelerator("aer", {std::make_pair("sim-type", "statevector")});
auto xasmCompiler = xacc::getCompiler("xasm");
auto ir = xasmCompiler->compile(R"(__qpu__ void ansatz(qbit q, double t) {
X(q[0]);
Ry(q[1], t);
CX(q[1], q[0]);
H(q[0]);
H(q[1]);
Measure(q[0]);
Measure(q[1]);
})",
accelerator);
// auto program = ir->getComposite("bell2");
auto program = ir->getComposite("ansatz");
// Expected results from deuteron_2qbit_xasm_X0X1
const std::vector<double> expectedResults{
0.0, -0.324699, -0.614213, -0.837166, -0.9694,
-0.996584, -0.915773, -0.735724, -0.475947, -0.164595,
0.164595, 0.475947, 0.735724, 0.915773, 0.996584,
0.9694, 0.837166, 0.614213, 0.324699, 0.0};
const auto angles =
xacc::linspace(-xacc::constants::pi, xacc::constants::pi, 20);
for (size_t i = 0; i < angles.size(); ++i) {
auto buffer = xacc::qalloc(2);
auto evaled = program->operator()({angles[i]});
accelerator->execute(buffer, evaled);
EXPECT_NEAR(buffer->getExpectationValueZ(), expectedResults[i], 1e-6);
}
}
TEST(AerAcceleratorTester, checkDeuteronVqeH2) {
// Use Qpp accelerator
auto accelerator =
xacc::getAccelerator("aer", {std::make_pair("sim-type", "statevector")});
// Create the N=2 deuteron Hamiltonian
auto H_N_2 = xacc::quantum::getObservable(
"pauli", std::string("5.907 - 2.1433 X0X1 "
"- 2.1433 Y0Y1"
"+ .21829 Z0 - 6.125 Z1"));
auto optimizer = xacc::getOptimizer("nlopt");
xacc::qasm(R"(
.compiler xasm
.circuit deuteron_ansatz
.parameters theta
.qbit q
X(q[0]);
Ry(q[1], theta);
CNOT(q[1],q[0]);
)");
auto ansatz = xacc::getCompiled("deuteron_ansatz");
// Get the VQE Algorithm and initialize it
auto vqe = xacc::getAlgorithm("vqe");
vqe->initialize({std::make_pair("ansatz", ansatz),
std::make_pair("observable", H_N_2),
std::make_pair("accelerator", accelerator),
std::make_pair("optimizer", optimizer)});
// Allocate some qubits and execute
auto buffer = xacc::qalloc(2);
vqe->execute(buffer);
// auto buffer = xacc::qalloc(2);
// accelerator->execute(buffer, program);
// Expected result: -1.74886
EXPECT_NEAR((*buffer)["opt-val"].as<double>(), -1.74886, 1e-4);
}
// buffer->print(std::cout);
TEST(AerAcceleratorTester, checkNoise) {
// CI test don't have access to IBM, turn this on if you want to run
// auto accelerator =
// xacc::getAccelerator("aer:ibmq_vigo", {std::make_pair("shots",
// 100)});
// auto xasmCompiler = xacc::getCompiler("xasm");
// auto ir = xasmCompiler->compile(R"(__qpu__ void bell2(qbit q) {
// H(q[0]);
// CX(q[0], q[1]);
// Measure(q[0]);
// Measure(q[1]);
// })",
// accelerator);
// auto program = ir->getComposite("bell2");
// auto buffer = xacc::qalloc(2);
// accelerator->execute(buffer, program);
// buffer->print(std::cout);
}
TEST(AerAcceleratorTester, checkShots) {
const int nbShots = 100;
{
auto accelerator =
xacc::getAccelerator("aer", {std::make_pair("shots", nbShots), std::make_pair("sim-type", "qasm")});
xacc::getAccelerator("aer", {std::make_pair("shots", nbShots),
std::make_pair("sim-type", "qasm")});
// Allocate some qubits
auto buffer = xacc::qalloc(2);
auto quilCompiler = xacc::getCompiler("quil");
......
......@@ -12,4 +12,4 @@
# *******************************************************************************/
add_xacc_test(AerAccelerator)
target_link_libraries(AerAcceleratorTester xacc)
target_link_libraries(AerAcceleratorTester xacc xacc-quantum-gate)
......@@ -35,23 +35,68 @@ void compiler_InitializeXACC(const char *qpu_backend, int shots) {
setAccelerator(qpu_backend, shots);
}
auto process_qpu_backend_str = [](const std::string &qpu_backend_str)
-> std::pair<std::string, HeterogeneousMap> {
bool has_extra_config = qpu_backend_str.find("[") != std::string::npos;
auto qpu_name =
(has_extra_config)
? qpu_backend_str.substr(0, qpu_backend_str.find_first_of("["))
: qpu_backend_str;
HeterogeneousMap options;
if (has_extra_config) {
auto first = qpu_backend_str.find_first_of("[");
auto second = qpu_backend_str.find_first_of("]");
auto qpu_config = qpu_backend_str.substr(first + 1, second - first - 1);
auto key_values = split(qpu_config, ',');
for (auto key_value : key_values) {
auto tmp = split(key_value, ':');
auto key = tmp[0];
auto value = tmp[1];
// check if int first, then double,
// finally just throw it in as a string
try {
auto i = std::stoi(value);
options.insert(key, i);
} catch (std::exception &e) {
try {
auto d = std::stod(value);
options.insert(key, d);
} catch (std::exception &e) {
options.insert(key, value);
}
}
}
}
return std::make_pair(qpu_name, options);
};
void setAccelerator(const char *qpu_backend) {
if (qpu) {
if (qpu_backend != qpu->name()) {
qpu = xacc::getAccelerator(qpu_backend);
const auto [qpu_name, config] = process_qpu_backend_str(qpu_backend);
qpu = xacc::getAccelerator(qpu_name, config);
}
} else {
qpu = xacc::getAccelerator(qpu_backend);
const auto [qpu_name, config] = process_qpu_backend_str(qpu_backend);
qpu = xacc::getAccelerator(qpu_name, config);
}
}
void setAccelerator(const char *qpu_backend, int shots) {
if (qpu) {
if (qpu_backend != qpu->name()) {
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)});
auto [qpu_name, config] = process_qpu_backend_str(qpu_backend);
config.insert("shots", shots);
qpu = xacc::getAccelerator(qpu_backend, config);
}
} else {
auto [qpu_name, config] = process_qpu_backend_str(qpu_backend);
config.insert("shots", shots);
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)});
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment