Skip to content
Snippets Groups Projects
Commit c6b2fe3a authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Starting on implementing ability to allocate subsets of qubit resources

parent 922ec502
No related branches found
No related tags found
No related merge requests found
......@@ -51,14 +51,17 @@ const std::string src("__qpu__ teleport () {\n"
int main (int argc, char** argv) {
// Create a convenient alias...
using Simple3QubitAcc = xacc::quantum::EigenAccelerator<3>;
using Simple6QubitAcc = xacc::quantum::EigenAccelerator<6>;
// Create a reference to the 3 qubit simulation Accelerator
auto qpu = std::make_shared<Simple3QubitAcc>();
auto qpu = std::make_shared<Simple6QubitAcc>();
// Allocate some qubits, give them a unique identifier...
auto qreg = qpu->allocate("qreg");
auto qreg2 = qpu->allocate("qreg", 0, 1, 2);
// Construct a new Program
xacc::Program quantumProgram(qpu, src);
......
......@@ -20,14 +20,33 @@ protected:
QubitState state;
QubitState subState;
bool usingSubstate;
public:
Qubits() :
state((int) std::pow(2, NumberOfQubits)) {
state((int) std::pow(2, NumberOfQubits)), usingSubstate(false) {
// Initialize to |000...000> state
state.setZero();
state(0) = 1.0;
}
template<typename ... ActiveBits>
Qubits(QubitState& currentState, ActiveBits ... activeBits) :
state(currentState), subState((int) std::pow(2, sizeof...(ActiveBits))),
usingSubstate(true) {
}
template<typename... SubBits>
auto allocateSubset(
SubBits... subset) -> decltype(std::shared_ptr<Qubits<sizeof...(SubBits)>>()) {
auto qubits = std::make_shared<Qubits<sizeof...(SubBits)>>(state, subset...);
return qubits;
}
void applyUnitary(Eigen::MatrixXcd& U) {
state = U * state;
}
......
......@@ -48,7 +48,7 @@ using QuantumGraphIR = xacc::GraphIR<GraphType>;
*
*/
template<const int NQubits>
class EigenAccelerator : public QPUGate<NQubits> {
class EigenAccelerator : virtual public QPUGate<NQubits> {
public:
/**
......@@ -265,4 +265,5 @@ protected:
#endif
......@@ -41,6 +41,6 @@ BOOST_AUTO_TEST_CASE(checkConstruction) {
Qubits<3> qubits;
BOOST_VERIFY(qubits.N == 3);
std::bitset<3> bits;
BOOST_VERIFY(bits == qubits.toBits());
BOOST_VERIFY(bits == qubits.measure());
}
......@@ -53,12 +53,13 @@ void ScaffoldCompiler::modifySource() {
std::map<int, int> cbitToQubit;
std::regex qbitName("qbit\\s.*");
qubitAllocationLine = (*std::sregex_iterator(kernelSource.begin(), kernelSource.end(),
qbitName)).str() + "\n";
std::vector<std::string> splitQbit;
boost::split(splitQbit, qubitAllocationLine, boost::is_any_of(" "));
qubitAllocationLine = (*std::sregex_iterator(kernelSource.begin(),
kernelSource.end(), qbitName)).str() + "\n";
std::vector<std::string> splitQbit;
boost::split(splitQbit, qubitAllocationLine, boost::is_any_of(" "));
auto qbitVarName = splitQbit[1].substr(0, splitQbit[1].find_first_of("["));
// Create Cbit to Qbit mapping
std::regex cbitName("cbit\\s.*");
auto it = std::sregex_iterator(kernelSource.begin(), kernelSource.end(),
cbitName);
......@@ -168,10 +169,6 @@ std::shared_ptr<IR> ScaffoldCompiler::compile() {
// This will throw if it fails.
auto qasm = scaffcc.getFlatQASMFromSource(kernelSource);
// Generate a GraphIR instance, ie a graph
// tensor references making up this QASM
// std::cout << "Flat QASM: \n" << qasm << "\n";
// Get the Qasm as a Graph...
auto circuitGraph = QasmToGraph::getCircuitGraph(qasm);
......
......@@ -185,20 +185,6 @@ public:
// Set how many layers are in this circuit
int maxLayer = layer+1;
// Print info...
// for (auto cn : gateOperations) {
// std::cout << "Gate Operation: \n";
// std::cout << "\tName: " << std::get<0>(cn.properties) << "\n";
// std::cout << "\tLayer: " << std::get<1>(cn.properties) << "\n";
// std::cout << "\tGate Vertex Id: " << std::get<2>(cn.properties) << "\n";
// std::cout << "\tActing Qubits: ";
// std::vector<int> qubits = std::get<3>(cn.properties);
// for (auto v : qubits) {
// std::cout << v << ", ";
// }
// std::cout << "\n\n";
// }
generateEdgesFromLayer(1, graph, gateOperations, 0);
return graph;
......@@ -214,7 +200,8 @@ public:
* @param conditionalGraphs
*/
static void linkConditionalQasm(qci::common::Graph<CircuitNode>& mainGraph,
std::vector<qci::common::Graph<CircuitNode>>& conditionalGraphs, std::vector<int>& conditionalQubits) {
std::vector<qci::common::Graph<CircuitNode>>& conditionalGraphs,
std::vector<int>& conditionalQubits) {
// At this point we have a main circuit graph,
// and one or more smaller conditional graphs (each with
......
......@@ -78,19 +78,26 @@ public:
* Return the current state of the bits
* @return
*/
virtual std::bitset<(size_t) Number> toBits() {
virtual std::bitset<(size_t) Number> measure() {
return bits;
}
template<typename... SubBits>
auto allocateSubset(
SubBits ... subset) ->
decltype(std::shared_ptr<AcceleratorBits<sizeof...(SubBits)>>()) {
}
virtual ~AcceleratorBits() {}
private:
protected:
/**
* The bits themselves
*/
std::bitset<(size_t)Number> bits;
std::vector<int> activeBits;
};
class IAccelerator : public qci::common::QCIObject {
......@@ -146,11 +153,11 @@ public:
* instances that transform XACC IR to be amenable to execution
* on the hardware.
*/
template<typename BitsType>
template<typename TotalBits>
class Accelerator : public IAccelerator {
static_assert(is_valid_bitstype<BitsType>::value, "Derived BitsType parameter must contain N int member for number of bits.");
static_assert(std::is_base_of<AcceleratorBits<BitsType::N>, BitsType>::value, "");
static_assert(is_valid_bitstype<TotalBits>::value, "Derived BitsType parameter must contain N int member for number of bits.");
static_assert(std::is_base_of<AcceleratorBits<TotalBits::N>, TotalBits>::value, "");
public:
......@@ -159,16 +166,38 @@ public:
*
* @return bits The AcceleratorBits derived type
*/
std::shared_ptr<BitsType> allocate(const std::string& variableNameId) {
if (!canAllocate(BitsType::N)) {
std::shared_ptr<TotalBits> allocate(const std::string& variableNameId) {
if (!canAllocate(TotalBits::N)) {
QCIError("Error in allocated requested bits");
}
bits = std::make_shared<BitsType>();
NBitsAllocated = BitsType::N;
bits = std::make_shared<TotalBits>();
NBitsAllocated = TotalBits::N;
bitVarId = variableNameId;
return bits;
}
/**
* Allocate some subset of Accelerator bit resources.
*
* @param variableNameId
* @param bitList
* @return
*/
template<typename... SubBits>
auto allocate(const std::string& variableNameId,
SubBits... bitList) -> decltype(std::declval<TotalBits>().allocateSubset(bitList...)) {
// FIXME CHECK THAT THEY PASSED IN LIST OF INTS
if (!canAllocate(sizeof...(SubBits))) {
QCIError("Error in allocated requested bits");
}
auto subsetBits = bits->allocateSubset(bitList...);
NBitsAllocated = (int) sizeof...(SubBits);
bitVarId = variableNameId;
return subsetBits;
}
/**
* Return the number of bits that the user most recently
* requested.
......@@ -210,7 +239,7 @@ protected:
/**
*
*/
std::shared_ptr<BitsType> bits;
std::shared_ptr<TotalBits> bits;
/**
* Return true if this Accelerator can allocate
......
......@@ -36,7 +36,6 @@
#include "AbstractFactory.hpp"
#include "QCIError.hpp"
#include "IR.hpp"
#include "Accelerator.hpp"
#include <ostream>
using namespace qci::common;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment