13 #ifndef IBM_PULSE_COMPOSITE_INSTRUCTION_HPP_ 14 #define IBM_PULSE_COMPOSITE_INSTRUCTION_HPP_ 16 #include "CompositeInstruction.hpp" 17 #include "pulse_instruction.hpp" 18 #include "InstructionIterator.hpp" 20 #include "expression_parsing_util.hpp" 21 #include "xacc_service.hpp" 26 #include <unordered_set> 32 public std::enable_shared_from_this<PulseComposite> {
35 void validateInstructionIndex(
const std::size_t idx) {
36 if (idx >= instructions.size()) {
37 xacc::XACCLogger::instance()->error(
38 "\nInvalid instruction index on CMD_DEF\n" 39 "CompositeInstruction:\nnInstructions() = " +
40 std::to_string(nInstructions()) +
"\nidx = " + std::to_string(idx));
46 void validateInstructionPtr(InstPtr inst) {
47 if (std::find(instructions.begin(), instructions.end(), inst) !=
48 std::end(instructions)) {
49 xacc::XACCLogger::instance()->error(
50 "\nInvalid instruction:\nThis instruction pointer already added to " 57 void errorCircuitParameter()
const {
58 xacc::XACCLogger::instance()->error(
59 "CMD_DEF Instruction parameter API not implemented.");
65 std::vector<InstPtr> instructions{};
66 std::vector<std::string> variables{};
67 std::vector<std::string> _requiredKeys{};
69 std::vector<std::size_t> qbits;
70 std::string cmdDefName =
"";
72 std::shared_ptr<ExpressionParsingUtil> parsingUtil;
74 std::complex<double> coefficient = 1.0;
75 std::string acc_signature =
"";
79 PulseComposite(
const std::string &name, std::vector<std::string> &vars)
80 : cmdDefName(name), variables(vars) {}
81 PulseComposite(
const std::string &name, std::vector<std::string> &&vars)
82 : cmdDefName(name), variables(vars) {}
85 : cmdDefName(other.cmdDefName), variables(other.variables),
86 instructions(other.instructions), parsingUtil(other.parsingUtil) {}
88 const std::string
name()
const override {
return cmdDefName; }
90 void setName(
const std::string name)
override { cmdDefName =
name; }
92 void mapBits(std::vector<std::size_t> bitMap)
override {
93 for (
auto &inst : instructions) {
94 inst->mapBits(bitMap);
97 void setBits(
const std::vector<std::size_t> bits)
override { qbits = bits; }
98 const std::vector<std::size_t> bits()
override {
return qbits; }
100 const std::string toString()
override {
101 std::string retStr =
"";
102 std::stringstream vs;
103 vs << getVariables();
104 retStr += vs.str() +
"\n";
105 for (
auto i : instructions) {
106 if (i->isEnabled()) {
107 if (i->isComposite() &&
110 retStr += i->name() +
"()\n";
112 retStr += i->toString() +
"\n";
120 getParameter(
const std::size_t idx)
const override {
121 errorCircuitParameter();
125 errorCircuitParameter();
127 std::vector<InstructionParameter> getParameters()
override {
128 errorCircuitParameter();
131 const int nParameters()
override {
132 errorCircuitParameter();
136 const int nRequiredBits()
const override {
return 0; }
138 void enable()
override {
139 for (
int i = 0; i < nInstructions(); i++) {
140 getInstruction(i)->enable();
144 void disable()
override {
145 for (
int i = 0; i < nInstructions(); i++) {
146 getInstruction(i)->disable();
150 const bool isAnalog()
const override {
return true; }
152 void persist(std::ostream &outStream)
override {}
153 void load(std::istream &inStream)
override {}
155 const int nInstructions()
override {
return instructions.size(); }
157 const int nChildren()
override {
return instructions.size(); }
159 InstPtr getInstruction(
const std::size_t idx)
override {
160 validateInstructionIndex(idx);
161 return instructions[idx];
164 std::vector<InstPtr> getInstructions()
override {
return instructions; }
165 void removeInstruction(
const std::size_t idx)
override {
166 validateInstructionIndex(idx);
167 instructions.erase(instructions.begin() + idx);
169 void replaceInstruction(
const std::size_t idx, InstPtr newInst)
override {
170 validateInstructionIndex(idx);
172 instructions[idx] = newInst;
174 void insertInstruction(
const std::size_t idx, InstPtr newInst)
override {
175 validateInstructionIndex(idx);
177 instructions.insert(instructions.begin() + idx, newInst);
180 void addInstruction(InstPtr instruction)
override {
182 validateInstructionPtr(instruction);
183 instructions.push_back(instruction);
185 void addInstructions(std::vector<InstPtr> &insts)
override {
186 for (
auto &i : insts)
189 void addInstructions(
const std::vector<InstPtr> &insts)
override {
190 for (
auto &i : insts)
194 bool hasChildren()
const override {
return !instructions.empty(); }
195 bool expand(
const HeterogeneousMap &runtimeOptions)
override {
return true; }
197 const std::vector<std::string> requiredKeys()
override {
198 return _requiredKeys;
201 void addVariable(
const std::string variableName)
override {
202 variables.push_back(variableName);
204 void addVariables(
const std::vector<std::string> &vars)
override {
205 variables.insert(variables.end(), vars.begin(), vars.end());
207 const std::vector<std::string> getVariables()
override {
209 std::vector<std::string> ret = variables;
210 for (
auto &i : instructions) {
211 if (i->isComposite()) {
214 ret.insert(ret.end(), vars.begin(), vars.end());
217 std::unordered_set<std::string> s(ret.begin(), ret.end());
218 ret.assign(s.begin(), s.end());
221 void replaceVariable(
const std::string variable,
222 const std::string newVariable)
override {
224 variables.begin(), variables.end(),
225 [&](
const std::string var) {
return var == variable; }, newVariable);
228 const std::size_t nVariables()
override {
return getVariables().size(); }
230 const int depth()
override {
return 0; }
231 const std::string persistGraph()
override {
return ""; }
232 std::shared_ptr<Graph> toGraph()
override {
return nullptr; }
236 const std::size_t nLogicalBits()
override {
239 std::set<std::size_t> bits;
242 auto inst = iter.
next();
243 if (!inst->isComposite()) {
244 for (
auto &b : inst->bits()) {
252 const std::size_t nPhysicalBits()
override {
255 std::size_t maxBit = 0;
258 auto inst = iter.
next();
259 if (!inst->isComposite()) {
260 for (
auto &b : inst->bits()) {
270 const std::set<std::size_t> uniqueBits()
override {
271 std::set<std::size_t> uniqueBits;
274 auto next = iter.
next();
275 if (!next->isComposite()) {
276 for (
auto &b : next->bits()) {
277 uniqueBits.insert(b);
285 std::shared_ptr<CompositeInstruction> enabledView()
override {
286 auto newF = std::make_shared<PulseComposite>(this->cmdDefName);
287 for (
int i = 0; i < nInstructions(); i++) {
288 auto inst = getInstruction(i);
289 if (inst->isEnabled()) {
290 newF->addInstruction(inst);
296 void setCoefficient(
const std::complex<double> c)
override {
299 const std::complex<double> getCoefficient()
override {
return coefficient; }
301 std::shared_ptr<CompositeInstruction>
302 operator()(
const std::vector<double> ¶ms)
override {
304 parsingUtil = xacc::getService<ExpressionParsingUtil>(
"exprtk");
306 variables.erase( std::unique( variables.begin(), variables.end() ), variables.end() );
307 std::vector<InstPtr> flatten;
310 auto inst = iter.
next();
311 if (!inst->isComposite()) {
312 flatten.emplace_back(inst);
316 auto evaluatedCircuit = std::make_shared<PulseComposite>(
"evaled_" +
name());
319 for (
auto inst : flatten) {
326 for (
int i = 0; i < inst->nParameters(); i++) {
327 if (inst->getParameter(i).isVariable()) {
330 if (parsingUtil->evaluate(p.toString(), variables, params, val)) {
331 updatedInst->setParameter(i, val);
333 updatedInst->setParameter(i, p);
336 auto a = inst->getParameter(i);
337 updatedInst->setParameter(i, a);
339 updatedInst->setBits(inst->bits());
343 evaluatedCircuit->addInstruction(updatedInst);
349 return evaluatedCircuit;
352 const std::string accelerator_signature()
override {
return acc_signature; }
353 void set_accelerator_signature(
const std::string signature)
override {
354 acc_signature = signature;
358 std::shared_ptr<Instruction> clone()
override {
359 return std::make_shared<PulseComposite>(*this);
const std::string name() const override
Definition: pulse_composite.hpp:88
const std::string description() const override
Definition: pulse_composite.hpp:89
std::shared_ptr< Instruction > next()
Definition: InstructionIterator.hpp:58
bool hasNext()
Definition: InstructionIterator.hpp:52
Definition: Accelerator.hpp:25
Definition: InstructionIterator.hpp:24
Definition: heterogeneous.hpp:45
Definition: pulse_instruction.hpp:22
Definition: CompositeInstruction.hpp:72
Definition: pulse_composite.hpp:31