Commit 8c732f90 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

setup execute on multiple buffers to look for unknown ancilla buffers in IR automatically



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 895956d2
......@@ -157,7 +157,7 @@ std::shared_ptr<IR> StaqCompiler::compile(const std::string &src,
transformations::synthesize_oracles(*prog);
optimization::simplify(*prog);
// at this point we have to find out if we have any ancilla
// registers
internal_staq::CountAncillas ancillas;
......
#include "xacc_internal_compiler.hpp"
#include "Utils.hpp"
#include "xacc.hpp"
#include "InstructionIterator.hpp"
......@@ -11,7 +12,6 @@ void compiler_InitializeXACC(const char *qpu_backend) {
xacc::Initialize();
setAccelerator(qpu_backend);
}
void setAccelerator(const char *qpu_backend) {
......@@ -80,16 +80,52 @@ void execute(AcceleratorBuffer *buffer, CompositeInstruction *program,
void execute(AcceleratorBuffer **buffers, const int nBuffers,
CompositeInstruction *program, double *parameters) {
// FIXME Should take vector of buffers, and we collapse them
// into a single unified buffer for execution, then set the
// measurement counts accordingly in postprocessing.
// Should take vector of buffers, and we collapse them
// into a single unified buffer for execution, then set the
// measurement counts accordingly in postprocessing.
std::vector<AcceleratorBuffer *> bvec(buffers, buffers + nBuffers);
std::vector<std::string> buffer_names;
for (auto &a : bvec)
buffer_names.push_back(a->name());
// We don't own this ptr, so create shared_ptr with empty deleter
auto program_as_shared = std::shared_ptr<CompositeInstruction>(
program, empty_delete<CompositeInstruction>());
// Do we have any unknown ancilla bits?
std::vector<std::string> possible_extra_buffers;
int possible_size = -1;
InstructionIterator it(program_as_shared);
while (it.hasNext()) {
auto &next = *it.next();
auto bnames = next.getBufferNames();
for (auto &bb : bnames) {
if (!xacc::container::contains(buffer_names, bb) &&
!xacc::container::contains(possible_extra_buffers, bb)) {
// we have an unknown buffer with name bb, need to figure out its size
// too
possible_extra_buffers.push_back(bb);
}
}
}
for (auto &possible_buffer : possible_extra_buffers) {
std::set<std::size_t> sizes;
InstructionIterator it2(program_as_shared);
while (it2.hasNext()) {
auto &next = *it2.next();
for (auto &bit : next.bits()) {
sizes.insert(bit);
}
}
auto size = *std::max_element(sizes.begin(),sizes.end());
auto extra = qalloc(size);
extra->setName(possible_buffer);
xacc::debug("[xacc_internal_compiler] Adding extra buffer " + possible_buffer + " of size " + std::to_string(size));
bvec.push_back(extra.get());
}
// Merge the buffers. Keep track of buffer_name to shift in
// all bit indices operating on that buffer_name, a map of
// buffer names to the buffer ptr, and start a map to collect
......@@ -107,10 +143,10 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
buf_map.insert({b->name(), b});
buf_counts.insert({b->name(), {}});
global_reg_size += b->size();
}
xacc::debug("[xacc_internal_compiler] Creating register of size " + std::to_string(global_reg_size));
xacc::debug("[xacc_internal_compiler] Creating register of size " +
std::to_string(global_reg_size));
auto tmp = xacc::qalloc(global_reg_size);
// Update Program bit indices based on new global
......@@ -130,7 +166,7 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
// FIXME Update buffer_names here too
std::vector<std::string> unified_buf_names;
for (int j = 0; j < next.nRequiredBits(); j++) {
unified_buf_names.push_back("q");
unified_buf_names.push_back("q");
}
next.setBufferNames(unified_buf_names);
}
......@@ -142,7 +178,7 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
for (auto &kv : tmp->getMeasurementCounts()) {
auto bitstring = kv.first;
if (qpu->getBitOrder() == Accelerator::BitOrder::MSB) {
std::reverse(bitstring.begin(), bitstring.end());
std::reverse(bitstring.begin(), bitstring.end());
}
for (int j = 0; j < shift_map_names.size(); j++) {
......@@ -151,10 +187,10 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
auto buff_name = shift_map_names[j];
auto buffer = buf_map[buff_name];
auto buffer_bitstring = bitstring.substr(shift, buffer->size());
auto buffer_bitstring = bitstring.substr(shift, buffer->size());
if (qpu->getBitOrder() == Accelerator::BitOrder::MSB) {
std::reverse(buffer_bitstring.begin(), buffer_bitstring.end());
std::reverse(buffer_bitstring.begin(), buffer_bitstring.end());
}
if (buf_counts[buff_name].count(buffer_bitstring)) {
......@@ -168,6 +204,8 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
for (auto &b : bvec) {
b->setMeasurements(buf_counts[b->name()]);
}
}
} // namespace internal_compiler
......
......@@ -58,12 +58,21 @@ TEST(InternalCompilerTester, checkMultipleBuffers) {
}
}
// module mult (multiplicand, multiplier, product);
// input [3:0] multiplicand;
// input [3:0] multiplier;
// output[7:0] product;
// assign product = multiplicand * multiplier;
// endmodule // mult
TEST(InternalCompilerTester, checkStaqAdd) {
if (!xacc::hasCompiler("staq")) {
return;
}
xacc::external::load_external_language_plugins();
setAccelerator("aer");
auto a = qalloc(4);
a.setName("a");
a.store();
......@@ -76,10 +85,6 @@ TEST(InternalCompilerTester, checkStaqAdd) {
c.setName("c");
c.store();
auto anc = qalloc(3);
anc.setName("anc");
anc.store();
auto src = R"(__qpu__ void add(qreg a, qreg b, qreg c) {
OPENQASM 2.0;
include "qelib1.inc";
......@@ -102,32 +107,71 @@ adder a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],c[0],c[1],c[2],c[3];
measure c -> result;
})";
auto circuit = compile("staq", src);
xacc::AcceleratorBuffer *bufs[4] = {a.results(), b.results(), c.results(),
anc.results()};
xacc::AcceleratorBuffer *bufs[3] = {a.results(), b.results(), c.results()};
// std::vector<xacc::AcceleratorBuffer*> bufs{q.results(),r.results()};
execute(bufs, 4, circuit);
auto counts = a.counts();
for (const auto &kv : counts) {
printf("%s: %i\n", kv.first.c_str(), kv.second);
}
counts = b.counts();
execute(bufs, 3, circuit);
// Get the counts of the result buffer
// should be 1000
auto counts = c.counts();
for (const auto &kv : counts) {
printf("%s: %i\n", kv.first.c_str(), kv.second);
}
counts = c.counts();
for (const auto &kv : counts) {
printf("%s: %i\n", kv.first.c_str(), kv.second);
}
counts = anc.counts();
for (const auto &kv : counts) {
printf("%s: %i\n", kv.first.c_str(), kv.second);
}
xacc::external::unload_external_language_plugins();
}
// TEST(InternalCompilerTester, checkStaqMult) {
// if (!xacc::hasCompiler("staq")) {
// return;
// }
// xacc::external::load_external_language_plugins();
// setAccelerator("aer");
// auto a = qalloc(2);
// a.setName("aa");
// a.store();
// auto b = qalloc(2);
// b.setName("bb");
// b.store();
// auto c = qalloc(4);
// c.setName("cc");
// c.store();
// auto src = R"(__qpu__ void add(qreg aa, qreg bb, qreg cc) {
// OPENQASM 2.0;
// include "qelib1.inc";
// oracle mult aa0,aa1,bb0,bb1,cc0,cc1,cc2,cc3 { "@CMAKE_SOURCE_DIR@/quantum/plugins/staq/compiler/tests/mult.v" }
// creg result[4];
// // a = 1
// x aa[0];
// //x aa[2];
// // b = 2
// x bb[1];
// //x bb[2];
// mult aa[0],aa[1],bb[0],bb[1],cc[0],cc[1],cc[2],cc[3];
// // measure
// measure cc -> result;
// })";
// auto circuit = compile("staq", src);
// xacc::AcceleratorBuffer *bufs[4] = {a.results(), b.results(), c.results()};
// execute(bufs, 3, circuit);
// auto counts = c.counts();
// for (const auto &kv : counts) {
// printf("%s: %i\n", kv.first.c_str(), kv.second);
// }
// xacc::external::unload_external_language_plugins();
// }
int main(int argc, char **argv) {
compiler_InitializeXACC();
xacc::set_verbose(true);
......
Supports Markdown
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