Loading examples/qrt/add_3_5.cpp 0 → 100644 +37 −0 Original line number Diff line number Diff line #include <qalloc> __qpu__ void add_3_5(qreg a, qreg b, qreg c) { using qcor::openqasm; oracle adder a0,a1,a2,a3,b0,b1,b2,b3,c0,c1,c2,c3 { "add_3_5.v" } creg result[4]; // a = 3 x a[0]; x a[1]; // b = 5 x b[0]; x b[2]; 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 measure c -> result; } int main(int argc, char** argv) { auto a = qalloc(4); auto b = qalloc(4); auto c = qalloc(4); // Execute on the quantum accelerator add_3_5(a, b, c); // Get the results and display auto counts = c.counts(); for (const auto & kv: counts) { printf("%s: %i\n", kv.first.c_str(), kv.second); } } examples/qrt/add_3_5.v 0 → 100644 +31 −0 Original line number Diff line number Diff line module top (\a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3],\c[0],\c[1],\c[2],\c[3]); input \a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3]; output \c[0],\c[1],\c[2],\c[3]; wire n386,n387,n388,n389,n390,n391,n392,n393,n394,n395,n396,n397,n398,n399,n400,n401,n402,n403,n404,n405,n406,n407,n408,n409,n410 ; assign n386 = \a[0] & ~\b[0] ; assign n387 = ~\a[0] & \b[0] ; assign \c[0] = n386 | n387; assign n389 = \a[0] & \b[0] ; assign n390 = ~\a[1] & ~\b[1] ; assign n391 = \a[1] & \b[1] ; assign n392 = ~n390 & ~n391; assign n393 = n389 & ~n392; assign n394 = ~n389 & n392; assign \c[1] = n393 | n394; assign n396 = n389 & ~n390; assign n397 = ~n391 & ~n396; assign n398 = ~\a[2] & ~\b[2] ; assign n399 = \a[2] & \b[2] ; assign n400 = ~n398 & ~n399; assign n401 = n397 & ~n400; assign n402 = ~n397 & n400; assign \c[2] = ~n401 & ~n402; assign n404 = ~n397 & ~n398; assign n405 = ~n399 & ~n404; assign n406 = ~\a[3] & ~\b[3] ; assign n407 = \a[3] & \b[3] ; assign n408 = ~n406 & ~n407; assign n409 = n405 & ~n408; assign n410 = ~n405 & n408; assign \c[3] = ~n409 & ~n410; endmodule handlers/token_collector/token_collector_util.cpp +150 −18 Original line number Diff line number Diff line Loading @@ -155,26 +155,30 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); } if (ss.str().find("oracle") == std::string::npos) { ss << terminating_char; } // std::cout << "COMPILING\n" // << function_prototype + "{" + ss.str() + "}" // << function_prototype + "{\n" + ss.str() + "\n}" // << "\n"; // FIXME, check canParse, and if not, then just write ss.str() to qrt_code // somehow // FIXME, may return multiple instructions return compiler ->compile("__qpu__ " + function_prototype + "{" + ss.str() + "}") ->getComposites()[0] ->getInstruction(0); ->compile("__qpu__ " + function_prototype + "{\n" + ss.str() + "\n}") ->getComposites()[0]; }; auto compiler = xacc::getCompiler("xasm"); auto terminating_char = compiler->get_statement_terminator(); std::stringstream qrt_code; std::string extra_preamble = ""; std::string extra_preamble = "", language = "xasm"; std::map<std::string, std::string> oracle_name_to_extra_preamble; std::map<std::string, int> creg_name_to_size; for (int i = 0; i < Toks.size(); i++) { auto current_token = Toks[i]; Loading @@ -183,7 +187,7 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, if (current_token.is(clang::tok::kw_using)) { // Found using // i+3 bc we skip using, qcor and ::; auto language = PP.getSpelling(Toks[i + 3]); language = PP.getSpelling(Toks[i + 3]); if (language == "openqasm") { // use staq language = xacc::hasCompiler("staq") ? "staq" : "openqasm"; Loading @@ -207,6 +211,103 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, continue; } if (current_token_str == "oracle") { if (language != "staq") { xacc::error("Error - must specify 'using qcor::openqasm;' before using " "staq openqasm code."); } std::stringstream slurp_oracle; i++; current_token = Toks[i]; std::string oracle_name = PP.getSpelling(current_token); slurp_oracle << "oracle " << oracle_name << " "; while (true) { i++; current_token = Toks[i]; slurp_oracle << PP.getSpelling(current_token); if (current_token.is(clang::tok::r_brace)) { break; } } auto preamble = slurp_oracle.str() + "\n"; oracle_name_to_extra_preamble.insert({oracle_name, preamble}); continue; } if (oracle_name_to_extra_preamble.count(current_token_str)) { // add the appropriate preamble here extra_preamble += oracle_name_to_extra_preamble[current_token_str]; auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } continue; } if (current_token_str == "measure") { // we have an ibm style measure, // so make sure that we map to individual measures // since we don't know the size of the qreg // next token is qreg name i++; current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); auto qreg_name = current_token_str; // next token could be [ or could be -> i++; current_token = Toks[i]; if (current_token.is(clang::tok::l_square)) { i--; i--; current_token = Toks[i]; // This we can parse, so just eat it up and get the Measure IR node out auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } // inst->accept(visitor); qrt_code << visitor->get_new_src(); } continue; } else { // the token is -> // the next one is the creg name i++; current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); auto creg_name = current_token_str; auto size = creg_name_to_size[creg_name]; for (int k = 0; k < size; k++) { qrt_code << "quantum::mz(" << qreg_name << "["<<k<<"]); // hello\n"; } continue; } } // FIXME may want this later // if (current_token_str == "qreg") { Loading Loading @@ -241,6 +342,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, if (current_token_str == "creg") { auto creg_name = PP.getSpelling(Toks[i + 1]); auto creg_size = PP.getSpelling(Toks[i + 3]); std::cout << "CREG: " << creg_name << ", " << creg_size << "\n"; creg_name_to_size.insert({creg_name, std::stoi(creg_size)}); std::stringstream sss; while (current_token.isNot(clang::tok::semi)) { sss << current_token_str << " "; Loading Loading @@ -293,11 +400,18 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, while (l_brace_count != 0) { // In here we have statements separated by compiler terminator // (default ';') auto inst = process_inst_stmt(i, compiler, current_token, auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } // inst->accept(visitor); qrt_code << visitor->get_new_src(); } // missing ';', eat it up too Loading Loading @@ -325,11 +439,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, qrt_code << "\n "; auto inst = process_inst_stmt(i, compiler, current_token, auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } Loading @@ -344,11 +464,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, // this is a quantum statement + terminating char // slurp up to the terminating char auto inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } } Loading @@ -360,6 +486,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, for (auto &buf : bufferNames) { OS << buf << ".setNameAndStore(\"" + buf + "\");\n"; } if (!oracle_name_to_extra_preamble.empty()) { // we had an oracle synthesis, just add an // anc registry preemptively OS << "auto anc = qalloc(" << std::numeric_limits<int>::max() << ");\n"; } if (shots > 0) { OS << "quantum::set_shots(" << shots << ");\n"; } Loading runtime/qrt/qrt.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx, void h(const qubit &qidx) { one_qubit_inst("H", qidx); } void x(const qubit &qidx) { one_qubit_inst("X", qidx); } void t(const qubit &qidx) { one_qubit_inst("T", qidx); } void tdg(const qubit &qidx) { one_qubit_inst("Tdg", qidx); } void rx(const qubit &qidx, const double theta) { one_qubit_inst("Rx", qidx, {theta}); Loading runtime/qrt/qrt.hpp +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx, void h(const qubit &qidx); void x(const qubit &qidx); void t(const qubit & qidx); void tdg(const qubit& qidx); void rx(const qubit &qidx, const double theta); void ry(const qubit &qidx, const double theta); Loading Loading
examples/qrt/add_3_5.cpp 0 → 100644 +37 −0 Original line number Diff line number Diff line #include <qalloc> __qpu__ void add_3_5(qreg a, qreg b, qreg c) { using qcor::openqasm; oracle adder a0,a1,a2,a3,b0,b1,b2,b3,c0,c1,c2,c3 { "add_3_5.v" } creg result[4]; // a = 3 x a[0]; x a[1]; // b = 5 x b[0]; x b[2]; 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 measure c -> result; } int main(int argc, char** argv) { auto a = qalloc(4); auto b = qalloc(4); auto c = qalloc(4); // Execute on the quantum accelerator add_3_5(a, b, c); // Get the results and display auto counts = c.counts(); for (const auto & kv: counts) { printf("%s: %i\n", kv.first.c_str(), kv.second); } }
examples/qrt/add_3_5.v 0 → 100644 +31 −0 Original line number Diff line number Diff line module top (\a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3],\c[0],\c[1],\c[2],\c[3]); input \a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3]; output \c[0],\c[1],\c[2],\c[3]; wire n386,n387,n388,n389,n390,n391,n392,n393,n394,n395,n396,n397,n398,n399,n400,n401,n402,n403,n404,n405,n406,n407,n408,n409,n410 ; assign n386 = \a[0] & ~\b[0] ; assign n387 = ~\a[0] & \b[0] ; assign \c[0] = n386 | n387; assign n389 = \a[0] & \b[0] ; assign n390 = ~\a[1] & ~\b[1] ; assign n391 = \a[1] & \b[1] ; assign n392 = ~n390 & ~n391; assign n393 = n389 & ~n392; assign n394 = ~n389 & n392; assign \c[1] = n393 | n394; assign n396 = n389 & ~n390; assign n397 = ~n391 & ~n396; assign n398 = ~\a[2] & ~\b[2] ; assign n399 = \a[2] & \b[2] ; assign n400 = ~n398 & ~n399; assign n401 = n397 & ~n400; assign n402 = ~n397 & n400; assign \c[2] = ~n401 & ~n402; assign n404 = ~n397 & ~n398; assign n405 = ~n399 & ~n404; assign n406 = ~\a[3] & ~\b[3] ; assign n407 = \a[3] & \b[3] ; assign n408 = ~n406 & ~n407; assign n409 = n405 & ~n408; assign n410 = ~n405 & n408; assign \c[3] = ~n409 & ~n410; endmodule
handlers/token_collector/token_collector_util.cpp +150 −18 Original line number Diff line number Diff line Loading @@ -155,26 +155,30 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); } if (ss.str().find("oracle") == std::string::npos) { ss << terminating_char; } // std::cout << "COMPILING\n" // << function_prototype + "{" + ss.str() + "}" // << function_prototype + "{\n" + ss.str() + "\n}" // << "\n"; // FIXME, check canParse, and if not, then just write ss.str() to qrt_code // somehow // FIXME, may return multiple instructions return compiler ->compile("__qpu__ " + function_prototype + "{" + ss.str() + "}") ->getComposites()[0] ->getInstruction(0); ->compile("__qpu__ " + function_prototype + "{\n" + ss.str() + "\n}") ->getComposites()[0]; }; auto compiler = xacc::getCompiler("xasm"); auto terminating_char = compiler->get_statement_terminator(); std::stringstream qrt_code; std::string extra_preamble = ""; std::string extra_preamble = "", language = "xasm"; std::map<std::string, std::string> oracle_name_to_extra_preamble; std::map<std::string, int> creg_name_to_size; for (int i = 0; i < Toks.size(); i++) { auto current_token = Toks[i]; Loading @@ -183,7 +187,7 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, if (current_token.is(clang::tok::kw_using)) { // Found using // i+3 bc we skip using, qcor and ::; auto language = PP.getSpelling(Toks[i + 3]); language = PP.getSpelling(Toks[i + 3]); if (language == "openqasm") { // use staq language = xacc::hasCompiler("staq") ? "staq" : "openqasm"; Loading @@ -207,6 +211,103 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, continue; } if (current_token_str == "oracle") { if (language != "staq") { xacc::error("Error - must specify 'using qcor::openqasm;' before using " "staq openqasm code."); } std::stringstream slurp_oracle; i++; current_token = Toks[i]; std::string oracle_name = PP.getSpelling(current_token); slurp_oracle << "oracle " << oracle_name << " "; while (true) { i++; current_token = Toks[i]; slurp_oracle << PP.getSpelling(current_token); if (current_token.is(clang::tok::r_brace)) { break; } } auto preamble = slurp_oracle.str() + "\n"; oracle_name_to_extra_preamble.insert({oracle_name, preamble}); continue; } if (oracle_name_to_extra_preamble.count(current_token_str)) { // add the appropriate preamble here extra_preamble += oracle_name_to_extra_preamble[current_token_str]; auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } continue; } if (current_token_str == "measure") { // we have an ibm style measure, // so make sure that we map to individual measures // since we don't know the size of the qreg // next token is qreg name i++; current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); auto qreg_name = current_token_str; // next token could be [ or could be -> i++; current_token = Toks[i]; if (current_token.is(clang::tok::l_square)) { i--; i--; current_token = Toks[i]; // This we can parse, so just eat it up and get the Measure IR node out auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } // inst->accept(visitor); qrt_code << visitor->get_new_src(); } continue; } else { // the token is -> // the next one is the creg name i++; current_token = Toks[i]; current_token_str = PP.getSpelling(current_token); auto creg_name = current_token_str; auto size = creg_name_to_size[creg_name]; for (int k = 0; k < size; k++) { qrt_code << "quantum::mz(" << qreg_name << "["<<k<<"]); // hello\n"; } continue; } } // FIXME may want this later // if (current_token_str == "qreg") { Loading Loading @@ -241,6 +342,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, if (current_token_str == "creg") { auto creg_name = PP.getSpelling(Toks[i + 1]); auto creg_size = PP.getSpelling(Toks[i + 3]); std::cout << "CREG: " << creg_name << ", " << creg_size << "\n"; creg_name_to_size.insert({creg_name, std::stoi(creg_size)}); std::stringstream sss; while (current_token.isNot(clang::tok::semi)) { sss << current_token_str << " "; Loading Loading @@ -293,11 +400,18 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, while (l_brace_count != 0) { // In here we have statements separated by compiler terminator // (default ';') auto inst = process_inst_stmt(i, compiler, current_token, auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } // inst->accept(visitor); qrt_code << visitor->get_new_src(); } // missing ';', eat it up too Loading Loading @@ -325,11 +439,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, qrt_code << "\n "; auto inst = process_inst_stmt(i, compiler, current_token, auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } Loading @@ -344,11 +464,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, // this is a quantum statement + terminating char // slurp up to the terminating char auto inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); auto comp_inst = process_inst_stmt(i, compiler, current_token, terminating_char, extra_preamble); { auto visitor = std::make_shared<qrt_mapper>(); inst->accept(visitor); xacc::InstructionIterator iter(comp_inst); while (iter.hasNext()) { auto next = iter.next(); if (!next->isComposite()) { next->accept(visitor); } } qrt_code << visitor->get_new_src(); } } Loading @@ -360,6 +486,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP, for (auto &buf : bufferNames) { OS << buf << ".setNameAndStore(\"" + buf + "\");\n"; } if (!oracle_name_to_extra_preamble.empty()) { // we had an oracle synthesis, just add an // anc registry preemptively OS << "auto anc = qalloc(" << std::numeric_limits<int>::max() << ");\n"; } if (shots > 0) { OS << "quantum::set_shots(" << shots << ");\n"; } Loading
runtime/qrt/qrt.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx, void h(const qubit &qidx) { one_qubit_inst("H", qidx); } void x(const qubit &qidx) { one_qubit_inst("X", qidx); } void t(const qubit &qidx) { one_qubit_inst("T", qidx); } void tdg(const qubit &qidx) { one_qubit_inst("Tdg", qidx); } void rx(const qubit &qidx, const double theta) { one_qubit_inst("Rx", qidx, {theta}); Loading
runtime/qrt/qrt.hpp +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx, void h(const qubit &qidx); void x(const qubit &qidx); void t(const qubit & qidx); void tdg(const qubit& qidx); void rx(const qubit &qidx, const double theta); void ry(const qubit &qidx, const double theta); Loading