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

Xacc integration #1

Open
wants to merge 7 commits into
base: xacc-integration
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
1 change: 1 addition & 0 deletions xacc_examples/Pulse_Control/Pulse_Control/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a repo for developing time and bandlimited pulse controls for quantum devices. Through the use of Trust Region Policy Optimization, a method of Deep Reinforcement Learning, we can optimize the fidelity of quantum logic gates through the construction of pulses in terms of Discrete Prolate Spheroidal Sequences.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from gym_pulsecontrol.envs.pulsecontrol_env import PulseEnv
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import gym
import xacc
import numpy as np
import scipy as sp
from gym import error, spaces, utils
from gym.utils import seeding

class PulseEnv(gym.Env):
metadata = {'render.modes': ['human']}

def __init__(self):
self._state = np.zeros(15)
#self._state = np.zeros(self.slepians_matrix.shape[1])
self.end_episode_rewards = []
self.current_reward = []
self.index = 0

def reward_function(self):
self.pulseData = (self._state * self.slepians_matrix).sum(axis=1)
# Add that square pulse instruction to XACC
pulseName = 'Slepian' + str(self.index)
print(pulseName)
xacc.addPulse(pulseName, self.pulseData)
q = xacc.qalloc(1)
# Create the quantum program that contains the slepian pulse
# and the drive channel (D0) is set on the instruction
provider = xacc.getIRProvider('quantum')
prog = provider.createComposite('pulse')
slepianPulse = provider.createInstruction(pulseName, [0])
slepianPulse.setChannel('d0')
prog.addInstruction(slepianPulse)
# Measure Q0 (using the number of shots that was specified above)
prog.addInstruction(xacc.gate.create("Measure", [0]))
self.qpu.execute(q, prog)
return q.computeMeasurementProbability('1')

def step(self, action):
a = action.copy()
self._state = self._state + a
self._state = np.clip(self._state, self.observation_space.low, self.observation_space.high)
self.index += 1
reward = self.reward_function()
print("REWARD IS ", reward)
done = bool((np.abs(1.0-reward) < 1e-4))
next_state = np.copy(self._state)
return np.array(next_state), reward, done, {}

def reset(self):
self._state = np.zeros(self.slepians_matrix.shape[1])
observation = np.copy(self._state)
return observation

def render(self, mode='human'):
print('Reward=', self.reward_function())

def close(self):
pass

@property
def action_space(self):
return spaces.Box(low=-0.25, high=0.25, shape=(15,))#shape=(self.n_orders,))

@property
def observation_space(self):
return spaces.Box(low=-5.0, high=5.0, shape=(15,))#shape=(self.n_orders,))
59 changes: 59 additions & 0 deletions xacc_examples/Pulse_Control/Pulse_Control/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#%%
import xacc
import gym
import spectrum
import json
#import gym_pulsecontrol
import numpy as np

from stable_baselines.common.policies import MlpPolicy
from stable_baselines import PPO2

# Total time, T, of control pulse
T = 100
# Number of pulse samples
nbSamples = 200
W = 0.05
k = int(2 * nbSamples * W)
n_orders = 15
# Initialize Slepians
Slepians, eigenvalues = spectrum.dpss(nbSamples, (nbSamples*W), k)
Slepians = Slepians[:, 0:n_orders]

gym.envs.register(
id='PulseControl-v0',
entry_point='gym_pulsecontrol.envs.pulsecontrol_env:PulseEnv',
)

env = gym.make('PulseControl-v0')
env.slepians_matrix = Slepians.copy()
env.n_orders = n_orders

hamiltonianJson = {
"description": "Hamiltonian of a one-qubit system.\n",
"h_str": ["-0.5*omega0*Z0", "omegaa*X0||D0"],
"osc": {},
"qub": {
"0": 2
},
"vars": {
"omega0": 6.2831853,
"omegaa": 0.0314159
}
}

# Create a pulse system model object
env.model = xacc.createPulseModel()
# Load the Hamiltonian JSON (string) to the system model
loadResult = env.model.loadHamiltonianJson(json.dumps(hamiltonianJson))
env.qpu = xacc.getAccelerator('QuaC', {'system-model': env.model.name(), 'shots': 1024 })
env.channelConfig = xacc.BackendChannelConfigs()
# Setting resolution of pulse
env.channelConfig.dt = nbSamples / T
# Driving on resonance with qubit
env.channelConfig.loFregs_dChannels = [1.0]
env.model.setChannelConfigs(env.channelConfig)

drl_model = PPO2('MlpPolicy', env,
verbose=0)
drl_model.learn(total_timesteps=50*n_orders)
6 changes: 6 additions & 0 deletions xacc_examples/Pulse_Control/Pulse_Control/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from setuptools import setup

setup(name='gym_pulsecontrol',
version='0.0.1',
install_requires=['gym', 'numpy', 'scipy', 'spectrum', 'tensorflow==1.15']
)
87 changes: 87 additions & 0 deletions xacc_examples/python/first_attempt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# One-qubit pulse simulation: Rabi oscillation
# We need to have the XACC install directory in the Python path.
# Just in case users haven't already done that, set it here.
import sys
from pathlib import Path
sys.path.insert(1, str(Path.home()) + '/.xacc')

# Import xacc and quaC python wrapper
import os
import xacc
import json
import spectrum

import numpy as np
import matplotlib
# CADES VM don't have display
matplotlib.use('Agg')
import matplotlib.pyplot as plt

# The Hamiltonian JSON object (OpenPulse format)
# omega0 = 2*pi, rotation speed: 100ns -> pi pulse (assume dt = 1)
hamiltonianJson = {
"description": "Hamiltonian of a one-qubit system.\n",
"h_str": ["-0.5*omega0*Z0", "omegaa*X0||D0"],
"osc": {},
"qub": {
"0": 2
},
"vars": {
"omega0": 6.2831853,
"omegaa": 0.0314159
}
}

# Create a pulse system model object
model = xacc.createPulseModel()

# Load the Hamiltonian JSON (string) to the system model
loadResult = model.loadHamiltonianJson(json.dumps(hamiltonianJson))

qpu = xacc.getAccelerator('QuaC', {'system-model': model.name(), 'shots': 1024 })
channelConfig = xacc.BackendChannelConfigs()

T = 100
# Number of sample points to realize a PI pulse
nbSamples = 1000 #512 # 100
# dt (time between data samples)
channelConfig.dt = nbSamples / T #1.0
# omega0 = 2*pi => freq = 1.0 (drive at resonance)
channelConfig.loFregs_dChannels = [1.0]
model.setChannelConfigs(channelConfig)

W = 0.02
k = int(2 * nbSamples * W)
n_orders = 36
# Initialize Slepians
Slepians, eigenvalues = spectrum.dpss(nbSamples, (nbSamples*W), k)
Slepians = Slepians[:, 0:n_orders]

state = 5 * np.ones(Slepians.shape[1])

# Square pulse with nbSamples elements
pulseData = (state * Slepians).sum(axis=1)
# Add that square pulse instruction to XACC
pulseName = 'Slepian'
xacc.addPulse(pulseName, pulseData)
q = xacc.qalloc(1)
# Create the quantum program that contains the square pulse
# and the drive channel (D0) is set on the instruction
provider = xacc.getIRProvider('quantum')
prog = provider.createComposite('pulse')
slepianPulse = provider.createInstruction(pulseName, [0])
slepianPulse.setChannel('d0')
prog.addInstruction(slepianPulse)
# Measure Q0 (using the number of shots that was specified above)
prog.addInstruction(xacc.gate.create("Measure", [0]))

# Run the simulation
qpu.execute(q, prog)
resultProb = q.computeMeasurementProbability('1')

print(resultProb)

# Plot the result
plt.plot(pulseData)
os.chdir(os.path.dirname(os.path.abspath(__file__)))
plt.savefig('Slepian.png')
2 changes: 1 addition & 1 deletion xacc_examples/python/one_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
i = 0
for width in pulseWidth:
# Square pulse with nbSamples elements
pulseData = np.ones(width)
pulseData = np.ones(int(width))
# Add that square pulse instruction to XACC
pulseName = 'square' + str(width)
xacc.addPulse(pulseName, pulseData)
Expand Down