GateFunction.hpp 6.43 KB
Newer Older
1
2
3
4
5
6
7
8
/*******************************************************************************
 * Copyright (c) 2017 UT-Battelle, LLC.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompanies this
 * distribution. The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License
 * is available at https://eclipse.org/org/documents/edl-v10.php
9
10
 *
 * Contributors:
11
12
 *   Alexander J. McCaskey - initial API and implementation
 *******************************************************************************/
Mccaskey, Alex's avatar
Mccaskey, Alex committed
13
14
#ifndef QUANTUM_GATEQIR_QFUNCTION_HPP_
#define QUANTUM_GATEQIR_QFUNCTION_HPP_
15

16
#include "Registry.hpp"
17
#include "Function.hpp"
18
#include "XACC.hpp"
19
20
21
22

namespace xacc {
namespace quantum {

23
24
25
26
27
/**
 * The GateFunction is a QFunction for gate-model
 * quantum computing. It is composed of QInstructions that
 * are themselves derivations of the GateInstruction class.
 */
28
class GateFunction: public virtual Function {
29
30

protected:
Mccaskey, Alex's avatar
Mccaskey, Alex committed
31

32
33
34
	/**
	 * The name of this function
	 */
Mccaskey, Alex's avatar
Mccaskey, Alex committed
35
36
	std::string functionName;

37
	std::list<InstPtr> instructions;
Mccaskey, Alex's avatar
Mccaskey, Alex committed
38

39
40
	std::vector<InstructionParameter> parameters;

41
42
	std::string tag = "";

43
44
45
46
47
	/**
	 * Map of Instruction Index to ( Instruction's Runtime Parameter Index, Dependent Variable name)
	 */
	std::map<int, std::pair<int, std::string>> cachedVariableInstructions;

48
49
public:

50
51
52
53
54
55
	/**
	 * The constructor, takes the function unique id and its name.
	 *
	 * @param id
	 * @param name
	 */
56
57
58
59
	GateFunction(const std::string& name) :
			functionName(name), parameters(
					std::vector<InstructionParameter> { }) {
	}
60
61
62
63
	GateFunction(const std::string& name,
			std::vector<InstructionParameter> params) :
			functionName(name), parameters(params) {
	}
64

65
66
67
68
69
70
71
72
73
	GateFunction(const std::string& name, const std::string& _tag) :
			functionName(name), parameters(
					std::vector<InstructionParameter> { }), tag(_tag) {
	}
	GateFunction(const std::string& name, const std::string& _tag,
			std::vector<InstructionParameter> params) :
			functionName(name), parameters(params), tag(_tag) {
	}

74
75
76
77
	GateFunction(const GateFunction& other) :
			functionName(other.functionName), parameters(other.parameters) {
	}

78
79
80
81
	virtual const std::string getTag() {
		return tag;
	}

82
83
84
85
86
87
	virtual void mapBits(std::vector<int> bitMap) {
		for (auto i : instructions) {
			i->mapBits(bitMap);
		}
	}

88
89
90
91
92
	virtual const int nInstructions() {
		return instructions.size();
	}

	virtual InstPtr getInstruction(const int idx) {
93
		InstPtr i;
94
		if (instructions.size() > idx) {
95
			i = *std::next(instructions.begin(), idx);
96
		} else {
97
			xacc::error("GateFunction getInstruction invalid instruction index - " + std::to_string(idx) + ".");
98
		}
99
		return i;
100
101
102
103
104
105
106
107
108
	}

	virtual std::list<InstPtr> getInstructions() {
		return instructions;
	}

	virtual void removeInstruction(const int idx) {
		instructions.remove(getInstruction(idx));
	}
109

Mccaskey, Alex's avatar
Mccaskey, Alex committed
110
111
112
113
114
115
	/**
	 * Add an instruction to this quantum
	 * intermediate representation.
	 *
	 * @param instruction
	 */
116
117
118
	virtual void addInstruction(InstPtr instruction) {
		instructions.push_back(instruction);
	}
119

Mccaskey, Alex's avatar
Mccaskey, Alex committed
120
121
122
123
124
125
126
	/**
	 * Replace the given current quantum instruction
	 * with the new replacingInst quantum Instruction.
	 *
	 * @param currentInst
	 * @param replacingInst
	 */
127
128
129
130
	virtual void replaceInstruction(const int idx, InstPtr replacingInst) {
		std::replace(instructions.begin(), instructions.end(),
				getInstruction(idx), replacingInst);
	}
Mccaskey, Alex's avatar
Mccaskey, Alex committed
131

132
133
134
135
136
	virtual void insertInstruction(const int idx, InstPtr newInst) {
		auto iter = std::next(instructions.begin(), idx);
		instructions.insert(iter, newInst);
	}

137
138
139
140
	/**
	 * Return the name of this function
	 * @return
	 */
141
142
143
	virtual const std::string getName() {
		return functionName;
	}
Mccaskey, Alex's avatar
Mccaskey, Alex committed
144

145
146
147
148
	/**
	 * Return the qubits this function acts on.
	 * @return
	 */
149
150
151
	virtual const std::vector<int> bits() {
		return std::vector<int> { };
	}
Mccaskey, Alex's avatar
Mccaskey, Alex committed
152

153
154
155
156
157
	/**
	 * Return an assembly-like string representation for this function .
	 * @param bufferVarName
	 * @return
	 */
158
159
160
161
162
163
164
	virtual const std::string toString(const std::string& bufferVarName) {
		std::string retStr = "";
		for (auto i : instructions) {
			retStr += i->toString(bufferVarName) + "\n";
		}
		return retStr;
	}
Mccaskey, Alex's avatar
Mccaskey, Alex committed
165

166
	virtual InstructionParameter getParameter(const int idx) const {
167
		if (idx + 1 > parameters.size()) {
168
			XACCLogger::instance()->error("Invalid Parameter requested.");
169
170
171
172
173
174
175
		}

		return parameters[idx];
	}

	virtual void setParameter(const int idx, InstructionParameter& p) {
		if (idx + 1 > parameters.size()) {
176
			XACCLogger::instance()->error("Invalid Parameter requested.");
177
178
179
180
181
		}

		parameters[idx] = p;
	}

182
183
184
185
	virtual void addParameter(InstructionParameter instParam) {
		parameters.push_back(instParam);
	}

186
187
188
189
	virtual std::vector<InstructionParameter> getParameters() {
		return parameters;
	}

190
191
192
193
194
195
196
197
	virtual bool isParameterized() {
		return nParameters() > 0;
	}

	virtual const int nParameters() {
		return parameters.size();
	}

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
	virtual void evaluateVariableParameters(
			std::vector<InstructionParameter> runtimeParameters) {

		std::map<std::string, InstructionParameter> varToValMap;

		int i = 0;
		for (auto funcParam : parameters) {
			varToValMap.insert(
					std::make_pair(boost::get<std::string>(funcParam),
							runtimeParameters[i]));
			i++;
		}

		for (const auto& gateIdVarName : cachedVariableInstructions) {
			auto inst = getInstruction(gateIdVarName.first);
			auto varInstDependsOn = gateIdVarName.second.second;
			auto instParamIdx = gateIdVarName.second.first;

			int indexOfRuntimeParam, counter = 0;
			for (auto p : parameters) {
				if (boost::get<std::string>(p) == varInstDependsOn) {
					indexOfRuntimeParam = counter;
					break;
				}
				counter++;
			}

			inst->setParameter(instParamIdx, runtimeParameters[indexOfRuntimeParam]);
		}

		i = 0;
229
230
231
232
		for (auto inst : instructions) {
			if (inst->isComposite()) {
				std::dynamic_pointer_cast<Function>(inst)->evaluateVariableParameters(
						runtimeParameters);
233
234
235
236
237
238
239
240
241
242
243
244
245
246
			} else if (inst->isParameterized() && inst->getName() != "Measure") {

				for (int j = 0; j < inst->nParameters(); ++j) {
					auto instParam = inst->getParameter(j);

					if (instParam.which() == 3) {
						// This is a variable
						auto variable = boost::get<std::string>(instParam);

						auto runtimeParameter = varToValMap[variable];

						inst->setParameter(j, runtimeParameter);

						cachedVariableInstructions.insert(std::make_pair(i, std::make_pair(j, variable)));
247
248
249
					}
				}
			}
250
			i++;
251
252
		}
	}
253

254
	DEFINE_VISITABLE()
Mccaskey, Alex's avatar
Mccaskey, Alex committed
255
256

};
257

Mccaskey, Alex's avatar
Mccaskey, Alex committed
258
259
}
}
260
261

#endif