Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new pulse instructions(set/shift) for phase and frequency #464

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 35 additions & 28 deletions quantum/plugins/ibm/accelerator/IBMAccelerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,13 +599,10 @@ void IBMAccelerator::execute(
if (qobj_type == "pulse") {
// if we need to use pulse mode, contribute the pulse library of the
// backend (if any)
if (!defaults_response.empty()) {
// Make sure we only contribute pulse cmd-def once
static bool contributed;
if (!contributed) {
contributed = true;
contributeInstructions();
}
// And make sure we only contribute pulse cmd-def once
if (!defaults_response.empty() && !contributed) {
contributed = true;
contributeInstructions();
}
}
// Get the correct QObject Generator
Expand Down Expand Up @@ -947,7 +944,16 @@ void IBMAccelerator::contributeInstructions(
xacc::contributeService("acquire", aq);
auto dl = std::make_shared<Pulse>("delay");
xacc::contributeService("delay", dl);
auto shiftf = std::make_shared<Pulse>("shiftf");
xacc::contributeService("shiftf", shiftf);
auto setf = std::make_shared<Pulse>("setf");
xacc::contributeService("setf", setf);
auto shiftp = std::make_shared<Pulse>("shiftp");
xacc::contributeService("shiftp", shiftp);
auto setp = std::make_shared<Pulse>("setp");
xacc::contributeService("setp", setp);


// Add "parametric_pulse"
auto parametricPulse = std::make_shared<Pulse>("parametric_pulse");
xacc::contributeService("parametric_pulse", parametricPulse);
Expand Down Expand Up @@ -1026,25 +1032,27 @@ void IBMAccelerator::contributeInstructions(
if (inst_name == "delay") {
inst->setDuration((*seq_iter)["duration"].get<int>());
}

if ((*seq_iter).find("phase") != (*seq_iter).end()) {
// we have phase too
auto p = (*seq_iter)["phase"];
if (p.is_string()) {
// this is a variable we have to keep track of
auto ptmp = p.get<std::string>();
// get true variable
ptmp.erase(
std::remove_if(ptmp.begin(), ptmp.end(),
[](char ch) { return ch == '(' || ch == ')'; }),
ptmp.end());

InstructionParameter phase(ptmp);
inst->setParameter(0, phase);

} else {
InstructionParameter phase(p.get<double>());
inst->setParameter(0, phase);
std::string numberParameterNames[] = {"phase", "frequency"};
for (const auto& numberName : numberParameterNames) {
if ((*seq_iter).find(numberName) != (*seq_iter).end()) {
// we have phase or frequency too
auto p = (*seq_iter)[numberName];
if (p.is_string()) {
// this is a variable we have to keep track of
auto ptmp = p.get<std::string>();
// get true variable
ptmp.erase(
std::remove_if(ptmp.begin(), ptmp.end(),
[](char ch) { return ch == '(' || ch == ')'; }),
ptmp.end());

InstructionParameter parameter(ptmp);
inst->setParameter(0, parameter);

} else {
InstructionParameter parameter(p.get<double>());
inst->setParameter(0, parameter);
}
}
}
} else {
Expand Down Expand Up @@ -1079,9 +1087,8 @@ void IBMAccelerator::contributeInstructions(

xacc::info("Contributing " + tmpName + " pulse composite.");
xacc::contributeService(tmpName, cmd_def);
contributed = true;
}
// }
// }
}

const std::string RestClient::post(const std::string &remoteUrl,
Expand Down
1 change: 1 addition & 0 deletions quantum/plugins/ibm/accelerator/IBMAccelerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ class IBMAccelerator : public Accelerator {
std::map<std::string, nlohmann::json> backendProperties;
std::string getBackendPropsResponse = "{}";
std::string defaults_response = "{}";
bool contributed = false;
std::string mode = "qasm";
int requested_n_qubits = 0;
bool filterByJobsLimit = false;
Expand Down
7 changes: 6 additions & 1 deletion quantum/plugins/ibm/accelerator/OpenPulseVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ class OpenPulseVisitor : public BaseInstructionVisitor,
inst.set_phase(i.getParameter(0).as<double>());
inst.set_t0(i.start());

std::vector<std::string> builtIns {"fc", "acquire", "parametric_pulse", "delay" };
std::vector<std::string> builtIns {"fc", "acquire", "parametric_pulse", "delay",
"setf","shiftf", "setp", "shiftp" };
if (std::find(builtIns.begin(), builtIns.end(), i.name()) == std::end(builtIns)) {
// add to default libr
xacc::ibm_pulse::PulseLibrary lib;
Expand Down Expand Up @@ -122,6 +123,10 @@ class OpenPulseVisitor : public BaseInstructionVisitor,
inst.set_pulse_params(pulseParameters.getString("parameters_json"));
}

if (i.name() == "setf" || i.name() == "shiftf") {
inst.set_frequency(i.getParameter(0).as<double>());
}

instructions.push_back(inst);

}
Expand Down
9 changes: 8 additions & 1 deletion quantum/plugins/ibm/accelerator/json/PulseQObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ class Instruction {
std::string name;
int64_t t0;
double phase;
double frequency;
std::vector<int64_t> memory_slot;
int64_t duration;
std::vector<int64_t> qubits;
Expand All @@ -215,6 +216,9 @@ class Instruction {
double get_phase() const { return phase; }
void set_phase(double value) { this->phase = value; }

double get_frequency() const { return frequency; }
void set_frequency(double value) { this->frequency = value; }

std::vector<int64_t> get_memory_slot() const { return memory_slot; }
void set_memory_slot(std::vector<int64_t> value) {
this->memory_slot = value;
Expand Down Expand Up @@ -459,7 +463,7 @@ inline void to_json(json &j, const xacc::ibm_pulse::Instruction &x) {

j["name"] = x.get_name();
j["t0"] = x.get_t0();
if (x.get_name() == "fc") {
if (x.get_name() == "fc" || x.get_name() == "setp" || x.get_name() == "shiftp") {
j["phase"] = x.get_phase();
}
if (x.get_name() == "acquire") {
Expand All @@ -477,6 +481,9 @@ inline void to_json(json &j, const xacc::ibm_pulse::Instruction &x) {
if (x.get_name() == "delay") {
j["duration"] = x.get_duration();
}
if (x.get_name() == "setf" || x.get_name() == "shiftf") {
j["frequency"] = x.get_frequency();
}
}

inline void from_json(const json &j, xacc::ibm_pulse::Experiment &x) {
Expand Down
92 changes: 91 additions & 1 deletion quantum/plugins/ibm/tests/IBMPulseRemoteTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,100 @@ TEST(IBMPulseRemoteTester, checkCnotPulse) {
}
#endif

// Check manipulations with phase and frequency
TEST(IBMPulseRemoteTester, sendPhaseFrequencyPulse) {
xacc::set_verbose(true);
auto acc = xacc::getAccelerator("ibm:ibmq_armonk", {{"mode", "pulse"}});
auto buffer = xacc::qalloc(1);
auto provider = xacc::getService<xacc::IRProvider>("quantum");
std::string jjson("{"
"\"pulse_library\": ["
"{\"name\": \"pulse1\", \"samples\": ["
"[0.004,0.009],[0.004,0.009],[0.004,0.009],[0.004,0.009],[0.004,0.009],[0.004,0.009],"
"[0.029,0.05],[0.029,0.05],[0.029,0.05],[0.029,0.05],[0.029,0.05],[0.029,0.05],"
"[0.135,0.18],[0.135,0.18],[0.135,0.18],[0.135,0.18],[0.135,0.18],[0.135,0.18],"
"[0.41,0.365],[0.41,0.365],[0.41,0.365],[0.41,0.365],[0.41,0.365],[0.41,0.365],"
"[0.8,0.355],[0.8,0.355],[0.8,0.355],[0.8,0.355],[0.8,0.355],[0.8,0.355],"
"[0.8,0.355],[0.8,0.355],"
"[0.8,-0.355],[0.8,-0.355],"
"[0.8,-0.355],[0.8,-0.355],[0.8,-0.355],[0.8,-0.355],[0.8,-0.355],[0.8,-0.355],"
"[0.41,-0.365],[0.41,-0.365],[0.41,-0.365],[0.41,-0.365],[0.41,-0.365],[0.41,-0.365],"
"[0.135,-0.18],[0.135,-0.18],[0.135,-0.18],[0.135,-0.18],[0.135,-0.18],[0.135,-0.18],"
"[0.029,-0.05],[0.029,-0.05],[0.029,-0.05],[0.029,-0.05],[0.029,-0.05],[0.029,-0.05],"
"[0.004,-0.009],[0.004,-0.009],[0.004,-0.009],[0.004,-0.009],[0.004,-0.009],[0.004,-0.009]]},"
"{\"name\": \"pulse2\", \"samples\": ["
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],"
"[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0],[0.1,0.0]"
"]}"
"]"
","
"\"cmd_def\":["
"{\"name\":\"test_phase\",\"qubits\":[0],\"sequence\":["
"{\"name\":\"setp\",\"ch\":\"d0\",\"t0\":0,\"phase\":1.57}"
","
"{\"name\":\"pulse2\",\"ch\":\"d0\",\"t0\":0}"
","
"{\"name\":\"shiftp\",\"ch\":\"d0\",\"t0\":0,\"phase\":0.1}"
","
"{\"name\":\"pulse1\",\"ch\":\"d0\",\"t0\":0}"
"]}"
","
"{\"name\":\"test_freq\",\"qubits\":[0],\"sequence\":["
"{\"name\":\"setf\",\"ch\":\"d0\",\"t0\":0,\"frequency\":5.1}"
","
"{\"name\":\"pulse1\",\"ch\":\"d0\",\"t0\":0}"
","
"{\"name\":\"shiftf\",\"ch\":\"d0\",\"t0\":0,\"frequency\":-0.21}"
","
"{\"name\":\"pulse2\",\"ch\":\"d0\",\"t0\":0}"
"]}"
","
"{\"name\":\"id2\",\"qubits\":[0],\"sequence\":[{\"name\":\"setf\",\"ch\":\"d0\",\"t0\":0,\"frequency\":5}]}"
"] "
"}");

acc->contributeInstructions(jjson);
{
// ibmq_armonk does not support setp/shiftp pulse operations.
// test only contributeInstructions()
auto cr = xacc::getContributedService<xacc::Instruction>("pulse::test_phase_0");
auto cr_comp = std::dynamic_pointer_cast<xacc::CompositeInstruction>(cr);

EXPECT_EQ(cr_comp->getInstructions().size(), 4);
std::string checkNames[] = {"setp", "pulse1", "shiftp", "pulse2"};
for( int nI = 0; nI < 4; ++nI ) {
EXPECT_EQ(cr_comp->getInstruction(nI)->name(), checkNames[nI] );
}
}

auto cr = xacc::getContributedService<xacc::Instruction>("pulse::test_freq_0");
auto cr_comp = std::dynamic_pointer_cast<xacc::CompositeInstruction>(cr);

EXPECT_EQ(cr_comp->getInstructions().size(), 4);
std::string checkNames[] = {"setf", "pulse1", "shiftf", "pulse2"};
for( int nI = 0; nI < 4; ++nI ) {
EXPECT_EQ(cr_comp->getInstruction(nI)->name(), checkNames[nI] );
}

auto f = provider->createComposite("tmp");
auto m0 = provider->createInstruction("Measure", {0});
f->addInstructions({ cr_comp, m0 });
acc->execute(buffer, f);
buffer->print();
}

int main(int argc, char **argv) {
xacc::Initialize(argc, argv);
::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS();
xacc::Finalize();
return ret;
}
}