Skip to content

Commit

Permalink
Merge pull request #113 from mit-han-lab/dev
Browse files Browse the repository at this point in the history
Dev update index
  • Loading branch information
Hanrui-Wang authored Apr 4, 2023
2 parents 1bd1fdd + c9fcfb6 commit 2b195b6
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 79 deletions.
84 changes: 37 additions & 47 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,64 +15,54 @@

.. raw:: html

<p align="center">
<embed>
<h2> <p align="center"> A PyTorch Library for Quantum Simulation and Quantum Machine Learning</p> </h2>

<h3> <p align="center"> Faster, Scalable, Easy Debugging, Easy Deployment on Real Machine</p> </h3>
<p align="center">
<a href="https://github.com/mit-han-lab/torchquantum/blob/master/LICENSE">
<img alt="MIT License" src="https://img.shields.io/github/license/mit-han-lab/torchquantum">
</a>
<a href="https://torchquantum.readthedocs.io/">
<img alt="Documentation" src="https://img.shields.io/readthedocs/torchquantum/main">
</a>
<a href="https://join.slack.com/t/torchquantum/shared_invite/zt-1ghuf283a-OtP4mCPJREd~367VX~TaQQ">
<img alt="Chat @ Slack" src="https://img.shields.io/badge/slack-chat-2eb67d.svg?logo=slack">
</a>
<a href="https://qmlsys.hanruiwang.me">
<img alt="Forum" src="https://img.shields.io/discourse/status?server=https%3A%2F%2Fqmlsys.hanruiwang.me%2F">
</a>
<a href="https://qmlsys.mit.edu">
<img alt="Website" src="https://img.shields.io/website?up_message=qmlsys&url=https%3A%2F%2Fqmlsys.mit.edu">
</a>

<a href="https://pypi.org/project/torchquantum/">
<img alt="Pypi" src="https://img.shields.io/pypi/v/torchquantum">
</a>
</p>
<br />
</embed>

.. raw:: html

</p>

.. raw:: html

<h2>

.. raw:: html

<p align="center">

A PyTorch Library for Quantum Simulation and Quantum Machine Learning

.. raw:: html

</p>

.. raw:: html

</h2>

.. raw:: html

<h3>

.. raw:: html

<p align="center">

Faster, Scalable, Easy Debugging, Easy Deployment on Real Machine

.. raw:: html

</p>

.. raw:: html

</h3>

|MIT License| |Read the Docs| |Discourse status| |Website|

👋 Welcome
==========

What it is doing
^^^^^^^^^^^^^^^^
What it does
^^^^^^^^^^^^

Quantum simulation framework based on PyTorch. It supports statevector
simulation and pulse simulation (coming soon) on GPUs. It can scale up
to the simulation of 30+ qubits with multiple GPUs. #### Who will
benefit
to the simulation of 30+ qubits with multiple GPUs.

Who will benefit
^^^^^^^^^^^^^^^^

Researchers on quantum algorithm design, parameterized quantum circuit
training, quantum optimal control, quantum machine learning, quantum
neural networks. #### Differences from Qiskit/Pennylane
neural networks.

Differences from Qiskit/Pennylane
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Dynamic computation graph, automatic gradient computation, fast GPU
support, batch model tersorized processing.
Expand Down
83 changes: 51 additions & 32 deletions examples/qaoa/max_cut_paramshift.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import torch
import torchquantum as tq
import torchquantum.functional as tqf

import random
import numpy as np

from torchquantum.functional import mat_dict

from torchquantum.plugins import tq2qiskit, qiskit2tq
from torchquantum.measurement import expval_joint_analytical

seed = 0
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)

from torchquantum.plugins import QiskitProcessor, op_history2qiskit



class MAXCUT(tq.QuantumModule):
"""computes the optimal cut for a given graph.
Expand Down Expand Up @@ -125,50 +124,45 @@ def circuit(self, qdev):
self.mixer(qdev, self.betas[i], i)
self.entangler(qdev, self.gammas[i], i)

def forward(self, measure_all=False):
def forward(self, use_qiskit):
"""
Apply the QAOA ansatz and only measure the edge qubit on z-basis.
Args:
if edge is None
"""
qdev = tq.QuantumDevice(n_wires=self.n_wires, device=self.betas.device)

self.circuit(qdev)
# print(tq.measure(qdev, n_shots=1024))
# compute the expectation value
# print(qdev.get_states_1d())
if measure_all is False:

if not use_qiskit:
self.circuit(qdev)
expVal = 0
for edge in self.input_graph:
pauli_string = self.edge_to_PauliString(edge)
expv = expval_joint_analytical(qdev, observable=pauli_string)
expVal += 0.5 * expv
# print(pauli_string, expv)
# print(expVal)
return expVal
else:
return tq.measure(qdev, n_shots=1024, draw_id=0)
# use qiskit to compute the expectation value
expVal = 0
for edge in self.input_graph:
pauli_string = self.edge_to_PauliString(edge)

with torch.no_grad():
self.circuit(qdev)
circ = op_history2qiskit(qdev.n_wires, qdev.op_history)

def main():
# create a input_graph
input_graph = [(0, 1), (0, 3), (1, 2), (2, 3)]
n_wires = 4
n_layers = 3
model = MAXCUT(n_wires=n_wires, input_graph=input_graph, n_layers=n_layers)
# model.to("cuda")
# model.to(torch.device("cuda"))
# circ = tq2qiskit(tq.QuantumDevice(n_wires=4), model)
# print(circ)
# print("The circuit is", circ.draw(output="mpl"))
# circ.draw(output="mpl")
# use backprop
# backprop_optimize(model, n_steps=300, lr=0.01)
# use parameter shift rule
param_shift_optimize(model, n_steps=500, step_size=0.01)
expv = self.qiskit_processor.process_circs_get_joint_expval([circ], pauli_string)[0]
expVal += 0.5 * expv
expVal = torch.Tensor([expVal])
return expVal



def shift_and_run(model, use_qiskit=False):


def shift_and_run(model, use_qiskit):
# flatten the parameters into 1D array

grad_betas = []
Expand Down Expand Up @@ -207,7 +201,7 @@ def shift_and_run(model, use_qiskit=False):
return model(use_qiskit), [grad_betas, grad_gammas]


def param_shift_optimize(model, n_steps=10, step_size=0.1):
def param_shift_optimize(model, n_steps=10, step_size=0.1, use_qiskit=False):
"""finds the optimal cut where parameter shift rule is used to compute the gradient"""
# optimize the parameters and return the optimal values
# print(
Expand All @@ -218,7 +212,7 @@ def param_shift_optimize(model, n_steps=10, step_size=0.1):
n_layers = model.n_layers
for step in range(n_steps):
with torch.no_grad():
loss, grad_list = shift_and_run(model)
loss, grad_list = shift_and_run(model, use_qiskit=use_qiskit)
# param_list = list(model.parameters())
# print(
# "The initial parameters are betas = {} and gammas = {}".format(
Expand Down Expand Up @@ -257,8 +251,33 @@ def param_shift_optimize(model, n_steps=10, step_size=0.1):
"""


def main(use_qiskit):
# create a input_graph
input_graph = [(0, 1), (0, 3), (1, 2), (2, 3)]
n_wires = 4
n_layers = 1
model = MAXCUT(n_wires=n_wires, input_graph=input_graph, n_layers=n_layers)

# set the qiskit processor
processor_simulation = QiskitProcessor(use_real_qc=False, n_shots=10000)
model.set_qiskit_processor(processor_simulation)

# firstly perform simulate
# model.to("cuda")
# model.to(torch.device("cuda"))
# circ = tq2qiskit(tq.QuantumDevice(n_wires=4), model)
# print(circ)
# print("The circuit is", circ.draw(output="mpl"))
# circ.draw(output="mpl")
# use backprop
# backprop_optimize(model, n_steps=300, lr=0.01)
# use parameter shift rule
param_shift_optimize(model, n_steps=500, step_size=0.01, use_qiskit=use_qiskit)


if __name__ == "__main__":
# import pdb
# pdb.set_trace()

main()
use_qiskit = False
main(use_qiskit)

0 comments on commit 2b195b6

Please sign in to comment.