Accelerator.hpp 6.96 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
/***********************************************************************************
 * Copyright (c) 2016, UT-Battelle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
12
 *   * Neither the name of the xacc nor the
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributors:
 *   Initial API and implementation - Alex McCaskey
 *
 **********************************************************************************/
#ifndef XACC_ACCELERATOR_HPP_
#define XACC_ACCELERATOR_HPP_

#include <string>
35
#include "IRTransformation.hpp"
36
37
#include <array>
#include <bitset>
38
39
40

namespace xacc {

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * Utility structs to help determine if
 * we have been given valid Vertices.
 */
template<typename T, typename = void>
struct is_valid_bitstype: std::false_type {
};
template<typename T>
struct is_valid_bitstype<T, decltype(std::declval<T>().N, void())> : std::true_type {
};

/**
 * The types of Accelerators that XACC interacts with
 */
enum AcceleratorType { qpu_gate, qpu_aqc, npu };

57
58
59
60
61
62
63
64
65
66
67
68
/**
 * The AcceleratorBits class provides a common
 * base class for allocating accelerator-specific
 * bit resources (for example, qubits). It takes an
 * integer template parameter at construction that indicates
 * the number of bits this AcceleratorBits models.
 *
 * Derived Accelerators should define a subclass of this
 * class that models the hardware.
 *
 * @author Alex McCaskey
 */
69
70
71
template<const int Number>
class AcceleratorBits {
public:
72
73
74
	/**
	 * Reference to the number of bits
	 */
75
	static constexpr int N = Number;
76
77
78
79
80

	/**
	 * Return the current state of the bits
	 * @return
	 */
81
	virtual std::bitset<(size_t) Number> measure() {
82
83
84
		return bits;
	}

85
86
87
88
89
	template<typename... SubBits>
	auto allocateSubset(
			SubBits ... subset) ->
			decltype(std::shared_ptr<AcceleratorBits<sizeof...(SubBits)>>()) {
	}
90
91
	virtual ~AcceleratorBits() {}

92
protected:
93
94
95
96
97
98

	/**
	 *  The bits themselves
	 */
	std::bitset<(size_t)Number> bits;

99
100
	std::vector<int> activeBits;

101
102
};

103
class IAccelerator : public qci::common::QCIObject {
104
public:
105
106
107
108
109
	/**
	 * Return the type of this Accelerator.
	 *
	 * @return type The Accelerator type - Gate or AQC QPU, or NPU
	 */
110
111
	virtual AcceleratorType getType() = 0;

112
113
114
115
116
	/**
	 * Return any IR Transformations that must be applied to ensure
	 * the compiled IR is amenable to execution on this Accelerator.
	 * @return
	 */
117
	virtual std::vector<IRTransformation> getIRTransformations() = 0;
118

119
120
121
122
123
	/**
	 * Execute the provided XACC IR on this attached Accelerator.
	 *
	 * @param ir
	 */
124
125
	virtual void execute(const std::shared_ptr<IR> ir) = 0;

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	/**
	 * Return the number of bits that the user most recently
	 * requested.
	 *
	 * @return nBits The number of requested bits
	 */
	virtual int getAllocationSize() = 0;

	/**
	 * Return the variable name provided upon bit allocation
	 * (for example - qreg for gate model quantum bits in (qbit qreg[2];))
	 *
	 * @return varName The name of the bits allocated.
	 */
	virtual const std::string getVariableName() = 0;
};

/**
 * The Accelerator class provides a high-level abstraction
 * for XACC's interaction with attached post-exascale
 * accelerators (quantum and neuromorphic processing units).
 *
 * Derived Accelerators must provide a valid execute implementation
 * that takes XACC IR and executes it on the attached hardware or
 * simulator.
 *
 * Derived Accelerators must provide a list of IRTransformation
 * instances that transform XACC IR to be amenable to execution
 * on the hardware.
 */
156
template<typename TotalBits>
157
158
class Accelerator : public IAccelerator {

159
160
	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, "");
161
162
163

public:

164
	/**
165
	 * Allocate bit resources (if needed).
166
	 *
167
	 * @return bits The AcceleratorBits derived type
168
	 */
169
170
	std::shared_ptr<TotalBits> allocate(const std::string& variableNameId) {
		if (!canAllocate(TotalBits::N)) {
171
172
			QCIError("Error in allocated requested bits");
		}
173
174
		bits = std::make_shared<TotalBits>();
		NBitsAllocated = TotalBits::N;
175
176
177
178
		bitVarId = variableNameId;
		return bits;
	}

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
	/**
	 * 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;
	}

201
202
203
204
205
206
	/**
	 * Return the number of bits that the user most recently
	 * requested.
	 *
	 * @return nBits The number of requested bits
	 */
207
208
209
	virtual int getAllocationSize() {
		return NBitsAllocated;
	}
210

211
212
213
214
215
216
	/**
	 * Return the variable name provided upon bit allocation
	 * (for example - qreg for gate model quantum bits in (qbit qreg[2];))
	 *
	 * @return varName The name of the bits allocated.
	 */
217
218
	virtual const std::string getVariableName() {
		return bitVarId;
219
220
	}

221
222
223
	/**
	 * Destructor
	 */
224
	virtual ~Accelerator() {}
225
226
227

protected:

228
229
230
231
	/**
	 * The number of bits allocated upon the most
	 * recent user request for bit resources.
	 */
232
233
	int NBitsAllocated = 0;

234
235
236
	/**
	 * The variable name of the bits
	 */
237
238
	std::string bitVarId;

239
240
241
	/**
	 *
	 */
242
	std::shared_ptr<TotalBits> bits;
243

244
245
246
247
248
249
	/**
	 * Return true if this Accelerator can allocate
	 * the provided number of bits.
	 * @param NBits The number of bits to allocate
	 * @return canAllocate True if can allocate, false if not.
	 */
250
	virtual bool canAllocate(const int NBits) = 0;
251
252


253
254
255
};
}
#endif