Skip to content
This repository has been archived by the owner on Aug 14, 2024. It is now read-only.

Hamiltonian Simulation benchmark implementation #25

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4725c09
Initial commit: Implemented QFT benchmark
raynelfss Jul 5, 2022
45ea077
Initial commit: Implemented QFT benchmark
raynelfss Jul 5, 2022
6704634
Small quality of life changes
raynelfss Jul 6, 2022
f7aa9e5
Created binary variables to improve readability
raynelfss Jul 6, 2022
e0537a6
Merged with upstream
raynelfss Jul 13, 2022
cc9b8b1
Delete games/applications/qasm/qft directory
raynelfss Jul 25, 2022
68344aa
Delete run_ft.py
raynelfss Jul 25, 2022
1dfa956
Initial implementation of the Hamiltonian Simulation Benchmark
raynelfss Jul 26, 2022
638eb47
Accepted changes from file reorganization
raynelfss Jul 26, 2022
832014c
Use package import for 'applications'
raynelfss Jul 26, 2022
7c1df5a
Merge branch 'Qiskit:main' into hamiltonian
raynelfss Jul 27, 2022
a1c7fb9
Update License to Apache
raynelfss Jul 29, 2022
5d8c4fb
Merge branch 'Qiskit:main' into hamiltonian
raynelfss Jul 29, 2022
4310abd
Merge branch 'main' into hamiltonian
raynelfss Aug 1, 2022
f7d8a67
Merge branch 'main' into hamiltonian
raynelfss Aug 6, 2022
bb86de6
Eliminated custom xx, yy and zz gates + some housekeeping and suggest…
raynelfss Aug 8, 2022
3f460ef
Merge branch 'main' into hamiltonian
raynelfss Aug 9, 2022
b8624e5
Merge branch 'main' into hamiltonian
raynelfss Aug 10, 2022
7779d68
Merge branch 'main' into hamiltonian
raynelfss Aug 10, 2022
67e07a7
Update red_queen/games/applications/run_hamiltonian_sim.py
raynelfss Aug 12, 2022
d03f58f
Merge branch 'main' into hamiltonian
raynelfss Aug 12, 2022
6cb0290
Merge branch 'Qiskit:main' into hamiltonian
raynelfss Mar 21, 2023
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
137 changes: 137 additions & 0 deletions red_queen/games/applications/qasm/hamiltonian_sim.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
OPENQASM 2.0;
include "qelib1.inc";
gate xx q0,q1 { h q0; h q1; cx q0,q1; rz(pi/300) q1; cx q0,q1; h q0; h q1; }
gate yy q0,q1 { s q0; s q1; h q0; h q1; cx q0,q1; rz(pi/300) q1; cx q0,q1; h q0; h q1; sdg q0; sdg q1; }
gate zz q0,q1 { cx q0,q1; rz(pi/300) q1; cx q0,q1; }
qreg q0[8];
creg c0[8];
x q0[0];
x q0[2];
x q0[4];
x q0[6];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
rx(-0.025608673) q0[0];
rx(0.0025855306) q0[1];
rx(0.035773022) q0[2];
rx(0.038562765) q0[3];
rx(0.049408275) q0[4];
rx(-0.041610481) q0[5];
rx(-0.030732634) q0[6];
rx(-0.00050771453) q0[7];
rz(0.0091920293) q0[0];
rz(-0.057871436) q0[1];
rz(0.051748089) q0[2];
rz(0.057287757) q0[3];
rz(0.023958939) q0[4];
rz(0.0059034422) q0[5];
rz(-0.041620088) q0[6];
rz(0.015768462) q0[7];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
xx q0[0],q0[1];
xx q0[2],q0[3];
xx q0[4],q0[5];
xx q0[6],q0[7];
xx q0[1],q0[2];
xx q0[3],q0[4];
xx q0[5],q0[6];
yy q0[0],q0[1];
yy q0[2],q0[3];
yy q0[4],q0[5];
yy q0[6],q0[7];
yy q0[1],q0[2];
yy q0[3],q0[4];
yy q0[5],q0[6];
zz q0[0],q0[1];
zz q0[2],q0[3];
zz q0[4],q0[5];
zz q0[6],q0[7];
zz q0[1],q0[2];
zz q0[3],q0[4];
zz q0[5],q0[6];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
rx(-0.025608673) q0[0];
rx(0.0025855306) q0[1];
rx(0.035773022) q0[2];
rx(0.038562765) q0[3];
rx(0.049408275) q0[4];
rx(-0.041610481) q0[5];
rx(-0.030732634) q0[6];
rx(-0.00050771453) q0[7];
rz(0.0091920293) q0[0];
rz(-0.057871436) q0[1];
rz(0.051748089) q0[2];
rz(0.057287757) q0[3];
rz(0.023958939) q0[4];
rz(0.0059034422) q0[5];
rz(-0.041620088) q0[6];
rz(0.015768462) q0[7];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
xx q0[0],q0[1];
xx q0[2],q0[3];
xx q0[4],q0[5];
xx q0[6],q0[7];
xx q0[1],q0[2];
xx q0[3],q0[4];
xx q0[5],q0[6];
yy q0[0],q0[1];
yy q0[2],q0[3];
yy q0[4],q0[5];
yy q0[6],q0[7];
yy q0[1],q0[2];
yy q0[3],q0[4];
yy q0[5],q0[6];
zz q0[0],q0[1];
zz q0[2],q0[3];
zz q0[4],q0[5];
zz q0[6],q0[7];
zz q0[1],q0[2];
zz q0[3],q0[4];
zz q0[5],q0[6];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
rx(-0.025608673) q0[0];
rx(0.0025855306) q0[1];
rx(0.035773022) q0[2];
rx(0.038562765) q0[3];
rx(0.049408275) q0[4];
rx(-0.041610481) q0[5];
rx(-0.030732634) q0[6];
rx(-0.00050771453) q0[7];
rz(0.0091920293) q0[0];
rz(-0.057871436) q0[1];
rz(0.051748089) q0[2];
rz(0.057287757) q0[3];
rz(0.023958939) q0[4];
rz(0.0059034422) q0[5];
rz(-0.041620088) q0[6];
rz(0.015768462) q0[7];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
xx q0[0],q0[1];
xx q0[2],q0[3];
xx q0[4],q0[5];
xx q0[6],q0[7];
xx q0[1],q0[2];
xx q0[3],q0[4];
xx q0[5],q0[6];
yy q0[0],q0[1];
yy q0[2],q0[3];
yy q0[4],q0[5];
yy q0[6],q0[7];
yy q0[1],q0[2];
yy q0[3],q0[4];
yy q0[5],q0[6];
zz q0[0],q0[1];
zz q0[2],q0[3];
zz q0[4],q0[5];
zz q0[6],q0[7];
zz q0[1],q0[2];
zz q0[3],q0[4];
zz q0[5],q0[6];
barrier q0[0],q0[1],q0[2],q0[3],q0[4],q0[5],q0[6],q0[7];
measure q0[0] -> c0[0];
measure q0[1] -> c0[1];
measure q0[2] -> c0[2];
measure q0[3] -> c0[3];
measure q0[4] -> c0[4];
measure q0[5] -> c0[5];
measure q0[6] -> c0[6];
measure q0[7] -> c0[7];
209 changes: 209 additions & 0 deletions red_queen/games/applications/run_hamiltonian_sim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# ------------------------------------------------------------------------------
# Part of Red Queen Project. This file is distributed under the Apache 2.0 License.
# See accompanying file /LICENSE for details.
# ------------------------------------------------------------------------------

# Copyright 2022 SRI-International organization

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# https://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# GitHub links:
# - Circuit: https://github.com/SRI-International/QC-App-Oriented-Benchmarks/
# blob/master/hamiltonian-simulation/qiskit/hamiltonian_simulation_benchmark.py
# - Pre-calculated data: https://github.com/SRI-International/QC-App-Oriented-Benchmarks/
# blob/master/hamiltonian-simulation/_common/precalculated_data.json
# Changes made:
# - Changes have been made to the circuit-generating functions to include numpy.
# - The version with individual xx, yy and zz_gates was used.
# - Other changes have been made for this code to work with red-queen.

"""Benchmark Hamiltonian Simulation Circuit"""

import os

import pytest

import numpy as np

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister

from red_queen.games.applications import backends, run_qiskit_circuit


QASM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "qasm")
NUM_QUBITS = 8

# Pre-calculated data from git repository
raynelfss marked this conversation as resolved.
Show resolved Hide resolved
H_X = [
-0.3841300947500583,
0.03878295861060144,
0.5365953230759468,
0.5784414723417195,
0.7411241249516469,
-0.6241572167558622,
-0.4609895087661635,
-0.007615718024277518,
0.4782434942274214,
-0.6100960167167189,
-0.6405095065481761,
0.07765251715030663,
-0.4344687907780449,
0.5218797389241974,
-0.46061411670810526,
-0.41296098137198967,
0.9248110232255489,
0.8264286523422202,
0.1363496908115518,
-0.029015291992941616,
]
H_Z = [
0.13788044023849122,
-0.8680715448211151,
0.7762213398005142,
0.8593163543481379,
0.35938408275225986,
0.08855163284966783,
-0.6243013156839929,
0.2365269243700283,
-0.2517444632292354,
0.867164336543846,
0.296282404856135,
0.3435823547580954,
0.8631471356486622,
0.3399761708363991,
-0.5357509772547095,
-0.4883312979088732,
-0.5500163526392827,
-0.8385986892423059,
-0.6319995154933682,
0.44989873651812795,
]
K = 3
W = 10
T = 0.01


# xx gate
def xx_gate(angle):
qc = QuantumCircuit(2, name="xx")
for i in range(2):
qc.h(i)
qc.cx(0, 1)
qc.rz(np.pi * angle, 1)
qc.cx(0, 1)
for i in range(2):
qc.h(i)

return qc
raynelfss marked this conversation as resolved.
Show resolved Hide resolved


# yy gate
def yy_gate(angle):
qc = QuantumCircuit(2, name="yy")
for i in range(2):
qc.s(i)
for i in range(2):
qc.h(i)
qc.cx(0, 1)
qc.rz(np.pi * angle, 1)
qc.cx(0, 1)
for i in range(2):
qc.h(i)
for i in range(2):
qc.sdg(i)

return qc
raynelfss marked this conversation as resolved.
Show resolved Hide resolved


# zz_gate
def zz_gate(angle):
qc = QuantumCircuit(2, name="zz")
qc.cx(0, 1)
qc.rz(np.pi * angle, 1)
qc.cx(0, 1)

return qc
raynelfss marked this conversation as resolved.
Show resolved Hide resolved


# Hamiltonian simulation circuit generator, where:
# n = number of qubits
# k_order = trotterization order (number of trotter steps)
# time = time the simulation runs.
# w = strength of disorder
# h_x and h_z = disordered fields.
def hamiltonian_sim(n: int, k_order: int, time, w: int, h_x, h_z):
raynelfss marked this conversation as resolved.
Show resolved Hide resolved
qr = QuantumRegister(n)
cr = ClassicalRegister(n)
qc = QuantumCircuit(qr, cr, name="Hamiltonian")
angle = time / k_order

# Create binary state of "10101010..."
for i in range(0, n, 2):
qc.x(qr[i])
qc.barrier()

# Apply k amount of trotterization steps
for i in range(k_order):

# Pauli spin
for j in range(n):
qc.rx(2 * angle * w * h_x[j], qr[j])
for j in range(n):
qc.rz(2 * angle * w * h_z[j], qr[j])
qc.barrier()

# Apply xx_gate:
for j in range(2):
for k in range(j % 2, n - 1, 2):
qc.append(xx_gate(angle).to_instruction(), [qr[k], qr[(k + 1) % n]])

# Apply yy_gate:
for j in range(2):
for k in range(j % 2, n - 1, 2):
qc.append(yy_gate(angle).to_instruction(), [qr[k], qr[(k + 1) % n]])

# Apply zz_gate:
for j in range(2):
for k in range(j % 2, n - 1, 2):
qc.append(zz_gate(angle).to_instruction(), [qr[k], qr[(k + 1) % n]])

qc.barrier()

# Measure all qubits
for qubit in range(n):
qc.measure(qr[qubit], cr[qubit])

return qc


@pytest.mark.qiskit
@pytest.mark.parametrize("optimization_level", [0, 1, 2, 3])
@pytest.mark.parametrize("backend", backends)
def bench_qiskit_ft(benchmark, optimization_level, backend):
raynelfss marked this conversation as resolved.
Show resolved Hide resolved
shots = 65536
# Generate binary string based on number of qubits
binary_string = ""
for i in range(NUM_QUBITS):
binary_string += "1" if i % 2 == 0 else "0"
raynelfss marked this conversation as resolved.
Show resolved Hide resolved
binary_string = binary_string[::-1]
expected_counts = {binary_string: shots}
benchmark.name = "Hamiltonian Simulation"
circ = QuantumCircuit.from_qasm_file(os.path.join(QASM_DIR, "hamiltonian_sim.qasm"))
benchmark.algorithm = f"Optimization level: {optimization_level} on {backend.name()}"
run_qiskit_circuit(benchmark, circ, backend, optimization_level, shots, expected_counts)


if __name__ == "__main__":
hamiltonian_sim(NUM_QUBITS, K, T, W, H_X[:NUM_QUBITS], H_Z[:NUM_QUBITS]).qasm(
filename=os.path.join(QASM_DIR, "hamiltonian_sim.qasm")
)