Commit a250f470 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding latest staq as tpl


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent f0c0b38e
......@@ -23,9 +23,8 @@ add_subdirectory(placement)
#add_subdirectory(scaffold)
add_subdirectory(xasm)
add_subdirectory(qpp)
if (STAQ_DIR)
add_subdirectory(staq)
endif()
add_subdirectory(staq)
find_library(QRACK_LIBRARY NAMES qrack)
if (QRACK_LIBRARY)
message("-- Found Qrack library (find_library(QRACK_LIBRARY NAMES qrack))")
......
......@@ -19,10 +19,11 @@ message(STATUS "${BoldGreen}Building Staq Compiler.${ColorReset}")
usfunctiongetresourcesource(TARGET ${LIBRARY_NAME} OUT SRC)
usfunctiongeneratebundleinit(TARGET ${LIBRARY_NAME} OUT SRC)
add_library(${LIBRARY_NAME} SHARED ${SRC})
target_include_directories(${LIBRARY_NAME}
PUBLIC compiler utils transformations ${STAQ_DIR}/include ${STAQ_DIR}/libs)
PUBLIC compiler utils transformations ${CMAKE_SOURCE_DIR}/tpls/staq/include ${CMAKE_SOURCE_DIR}/tpls/staq/libs)
target_link_libraries(${LIBRARY_NAME}
PUBLIC xacc xacc-quantum-gate
......
# Instructions for building XACC with Staq Support
Simply add the following argument to your cmake call
```
-DSTAQ_DIR=/path/to/staq
```
......@@ -31,11 +31,13 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
const HeterogeneousMap &options) {
if (!qpu) {
xacc::warning("[SwapShort Placement] Provided QPU was null. Cannot run shortest path swap placement.");
return;
xacc::warning("[SwapShort Placement] Provided QPU was null. Cannot run "
"shortest path swap placement.");
return;
}
// First get total number of qubits on device
// First get total number of qubits on device
std::set<int> qbitIdxs;
auto connectivity = qpu->getConnectivity();
for (auto &edge : connectivity) {
......@@ -60,16 +62,17 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
auto staq = xacc::getCompiler("staq");
auto src = staq->translate(program);
std::cout <<"initial translate:\n" << src << "\n";
std::cout << "initial translate:\n" << src << "\n";
// parse that to get staq ast
auto prog = parser::parse_string(src);
mapping::Device device(qpu->getSignature(), nQubits, adj);//, oneq,couplings);
mapping::Device device(qpu->getSignature(), nQubits,
adj); //, oneq,couplings);
auto layout = mapping::compute_basic_layout(device, *prog);
mapping::apply_layout(layout, *prog);
layout = mapping::compute_basic_layout(device, *prog);
mapping::apply_layout(layout, device, *prog);
// layout = mapping::compute_basic_layout(device, *prog);
mapping::apply_layout(layout, *prog);
// mapping::apply_layout(layout, device, *prog);
std::cout << *prog << "\n";
mapping::map_onto_device(device, *prog);
......@@ -80,7 +83,7 @@ void SwapShort::apply(std::shared_ptr<CompositeInstruction> program,
prog->pretty_print(ss);
src = ss.str();
std::cout << "Final:\n" << src << "\n";
std::cout << "Final:\n" << src << "\n";
auto ir = staq->compile(src);
// reset the program and add optimized instructions
......
......@@ -37,7 +37,7 @@ public:
std::vector<std::pair<int, int>> getConnectivity() override { return edges; }
};
TEST(MappingTester, checkSwapShort) {
TEST(Staq_MappingTester, checkSwapShort) {
auto qpu = std::make_shared<AcceleratorWithConnectivity>(
std::vector<std::pair<int, int>>{{0, 1},
......
......@@ -15,7 +15,7 @@
#include "xacc.hpp"
#include "xacc_service.hpp"
TEST(RotationFoldingTester, checkSimple) {
TEST(Staq_RotationFoldingTester, checkSimple) {
auto irt = xacc::getIRTransformation("rotation-folding");
auto compiler = xacc::getCompiler("xasm");
auto program = compiler->compile(R"(__qpu__ void test_t_t(qreg q) {
......
MIT License
Copyright (c) 2019 - 2020 softwareQ Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Version 1.2 - 13 May 2020
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
/**
* \file ast/ast.hpp
*/
#include "ast/visitor.hpp"
#include "ast/base.hpp"
#include "ast/expr.hpp"
#include "ast/stmt.hpp"
#include "ast/decl.hpp"
#include "ast/program.hpp"
#include "ast/semantic.hpp"
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* \file ast/base.hpp
* \brief openQASM syntax trees
*/
#pragma once
#include "parser/position.hpp"
#include "visitor.hpp"
#include <set>
#include <memory>
namespace staq {
namespace ast {
template <typename T>
using ptr = std::unique_ptr<T>;
using symbol = std::string;
/**
* \class staq::ast::ASTNode
* \brief Base class for AST nodes
*/
class ASTNode {
static int& max_uid_() {
static int v;
return v;
} ///< the maximum uid that has been assigned
protected:
const int uid_; ///< the node's unique ID
const parser::Position pos_; ///< the node's source code position
public:
ASTNode(parser::Position pos) : uid_(++max_uid_()), pos_(pos) {}
virtual ~ASTNode() = default;
/**
* \brief Get the ID of the node
*
* \return The node's unique ID
*/
int uid() const { return uid_; }
/**
* \brief Get the position of the node
*
* \return The node's position in source
*/
parser::Position pos() const { return pos_; }
/**
* \brief Provides dispatch for the Visitor pattern
*/
virtual void accept(Visitor& visitor) = 0;
/**
* \brief Print the formatted QASM source code of the node
*
* \param os Output stream
*/
virtual std::ostream& pretty_print(std::ostream& os) const = 0;
/**
* \brief Generate a deep copy of the node
*/
virtual ASTNode* clone() const = 0;
/**
* \brief Extraction operator override
*
* Extraction is non-virtual and delegates to pretty_print
*
* \param os Output stream
* \param node Node to print
*/
friend std::ostream& operator<<(std::ostream& os, const ASTNode& node) {
return node.pretty_print(os);
}
};
} // namespace ast
} // namespace staq
/*
* This file is part of staq.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* \file ast/decl.hpp
* \brief openQASM declarations
*/
#pragma once
#include "stmt.hpp"
#include <list>
namespace staq {
namespace ast {
static const std::set<std::string_view> qelib_defs{
"u3", "u2", "u1", "cx", "id", "u0", "x", "y", "z",
"h", "s", "sdg", "t", "tdg", "rx", "ry", "rz", "cz",
"cy", "swap", "ch", "ccx", "crz", "cu1", "cu3"};
/**
* \brief Tests whether identifier is part of the standard openQASM qelib or not
*
* \param id Identifier
* \return True if \a id is part of the standard openQASM qelib, false otherwise
*/
inline bool is_std_qelib(const std::string& id) {
return qelib_defs.find(id) != qelib_defs.end();
}
/**
* \class staq::ast::Decl
* \brief Base class for openQASM declarations
*
* Declarations are attribute classes as they can occur in different
* statement contexts. To avoid diamond inheritance, any derived declaration
* should also inherit from a statement class
*/
class Decl {
protected:
symbol id_; ///< the name of the declaration
public:
Decl(symbol id) : id_(id) {}
virtual ~Decl() = default;
/**
* \brief Return the name being declared
*
* \return Constant reference to the identifier
*/
const symbol& id() { return id_; }
};
/**
* \class staq::ast::GateDecl
* \brief Class for gate declarations
* \see staq::ast::Stmt
* \see staq::ast::Decl
*/
class GateDecl final : public Stmt, public Decl {
bool opaque_; ///< whether the declaration is opaque
std::vector<symbol> c_params_; ///< classical parameters
std::vector<symbol> q_params_; ///< quantum parameters
std::list<ptr<Gate>> body_; ///< gate body
public:
/**
* \brief Constructs a gate declaration
*
* \param pos The source position
* \param id The gate identifier
* \param c_params List of classical parameters
* \param q_params List of quantum parameters
* \param body List of gate statements
*/
GateDecl(parser::Position pos, symbol id, bool opaque,
std::vector<symbol> c_params, std::vector<symbol> q_params,
std::list<ptr<Gate>>&& body)
: Stmt(pos), Decl(id), opaque_(opaque), c_params_(c_params),
q_params_(q_params), body_(std::move(body)) {}
/**
* \brief Protected heap-allocated construction
*/
static ptr<GateDecl> create(parser::Position pos, symbol id, bool opaque,
std::vector<symbol> c_params,
std::vector<symbol> q_params,
std::list<ptr<Gate>>&& body) {
return std::make_unique<GateDecl>(pos, id, opaque, c_params, q_params,
std::move(body));
}
/**
* \brief Whether the declaration is opaque
*
* \return true is the declaration is opaque
*/
bool is_opaque() { return opaque_; }
/**
* \brief Get the classical parameter list
*
* \return Reference to the list of classical parameter names
*/
std::vector<symbol>& c_params() { return c_params_; }
/**
* \brief Get the quantum parameter list
*
* \return Reference to the list of quantum parameter names
*/
std::vector<symbol>& q_params() { return q_params_; }
/**
* \brief Get the gate body
*
* \return Reference to the body of the gate as a list of gate statements
*/
std::list<ptr<Gate>>& body() { return body_; }
/**
* \brief Apply a function to each statement of the gate
*
* \param f A void function taking a reference to a Gate
*/
void foreach_stmt(std::function<void(Gate&)> f) {
for (auto it = body_.begin(); it != body_.end(); it++)
f(**it);
}
/**
* \brief Get an iterator to the beginning of the body
*
* \return std::list iterator
*/
std::list<ptr<Gate>>::iterator begin() { return body_.begin(); }
/**
* \brief Get an iterator to the end of the body
*
* \return std::list iterator
*/
std::list<ptr<Gate>>::iterator end() { return body_.end(); }
void accept(Visitor& visitor) override { visitor.visit(*this); }
std::ostream& pretty_print(std::ostream& os,
bool suppress_std) const override {
if (suppress_std && is_std_qelib(id_))
return os;
os << (opaque_ ? "opaque " : "gate ") << id_;
if (c_params_.size() > 0) {
os << "(";
for (auto it = c_params_.begin(); it != c_params_.end(); it++) {
os << (it == c_params_.begin() ? "" : ",") << *it;
}
os << ")";
}
os << " ";
for (auto it = q_params_.begin(); it != q_params_.end(); it++) {
os << (it == q_params_.begin() ? "" : ",") << *it;
}
if (opaque_) {
os << ";\n";
} else {
os << " {\n";
for (auto it = body_.begin(); it != body_.end(); it++) {
os << "\t" << **it;
}
os << "}\n";
}
return os;
}
GateDecl* clone() const override {
std::list<ptr<Gate>> tmp;
for (auto it = body_.begin(); it != body_.end(); it++) {
tmp.emplace_back(ptr<Gate>((*it)->clone()));
}
return new GateDecl(pos_, id_, opaque_, c_params_, q_params_,
std::move(tmp));
}
};
/**
* \class staq::ast::OracleDecl
* \brief Class for oracle declarations
* \see staq::ast::Decl
*/
class OracleDecl final : public Stmt, public Decl {
std::vector<symbol> params_; ///< quantum parameters
symbol fname_; ///< filename of external declaration
public:
/**
* \brief Constructs an oracle declaration
*
* \param pos The source position
* \param id The gate identifier
* \param params List of quantum parameters
* \param fname Filename defining the classical logic
*/
OracleDecl(parser::Position pos, symbol id, std::vector<symbol> params,
symbol fname)
: Stmt(pos), Decl(id), params_(params), fname_(fname) {}
/**
* \brief Protected heap-allocated construction
*/
static ptr<OracleDecl> create(parser::Position pos, symbol id,
std::vector<symbol> params, symbol fname) {
return std::make_unique<OracleDecl>(pos, id, params, fname);
}
/**
* \brief Get the parameter list
*
* \return Reference to the list of quantum parameter names
*/
std::vector<symbol>& params() { return params_; }
/**
* \brief Get the filename
*
* \return Constant reference to the filename
*/
const symbol& fname() { return fname_; }
void accept(Visitor& visitor) override { visitor.visit(*this); }
std::ostream& pretty_print(std::ostream& os, bool) const override {
os << "oracle " << id_ << " ";
for (auto it = params_.begin(); it != params_.end(); it++) {
os << (it == params_.begin() ? "" : ",") << *it;
}
os << " { \"" << fname_ << "\" }\n";
return os;
}
OracleDecl* clone() const override {
return new OracleDecl(pos_, id_, params_, fname_);
}
};
/**
* \class staq::ast::RegisterDecl
* \brief Class for register declarations
* \see staq::ast::Decl
*/
class RegisterDecl final : public Stmt, public Decl {
bool quantum_; ///< whether the register is quantum
int size_; ///< the size of the register
public:
/**
* \brief Constructs a register declaration
*
* \param pos The source position
* \param id The register identifier
* \param quantum whether the register is a quantum register
* \param size the size of the register
*/
RegisterDecl(parser::Position pos, symbol id, bool quantum, int size)
: Stmt(pos), Decl(id), quantum_(quantum), size_(size) {}
/**
* \brief Protected heap-allocated construction
*/
static ptr<RegisterDecl> create(parser::Position pos, symbol id,
bool quantum, int size) {
return std::make_unique<RegisterDecl>(pos, id, quantum, size);
}
/**
* \brief Whether the register is quantum or classical
*
* \return true if the register is quantum
*/
bool is_quantum() { return quantum_; }
/**
* \brief Get the size of the register
*
* \return The size of the register
*/
int size() { return size_; }
void accept(Visitor& visitor) override { visitor.visit(*this); }
std::ostream& pretty_print(std::ostream& os, bool) const override {
os << (quantum_ ? "qreg " : "creg ") << id_ << "[" << size_ << "];\n";
return os;
}
RegisterDecl* clone() const override {
return new RegisterDecl(pos_, id_, quantum_, size_);
}
};
/**
* \class staq::ast::AncillaDecl
* \brief Class for local register declarations
* \see staq::ast::Decl
*/
class AncillaDecl final : public Gate, public Decl {
bool dirty_; ///< whether the register can be dirty
int size_; ///< the size of the register
public:
/**
* \brief Constructs a register declaration
*
* \param pos The source position
* \param id The register identifier
* \param dirty Whether the register is dirty
* \param size The size of the register
*/
AncillaDecl(parser::Position pos, symbol id, bool dirty, int size)
: Gate(pos), Decl(id), dirty_(dirty), size_(size) {}
/**