Skip to content

Commit

Permalink
Added btc_ph.py to BTC_04_PH
Browse files Browse the repository at this point in the history
  • Loading branch information
gonfeco committed Sep 6, 2023
1 parent 97cefdc commit 6f69d36
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 4 deletions.
48 changes: 44 additions & 4 deletions tnbs/BTC_04_PH/PH/ansatzes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import numpy as np
import qat.lang.AQASM as qlm
from qat.core import Result
from qat.fermion.circuits import make_ldca_circ, make_general_hwe_circ


def ansatz_qlm_01(nqubits=7, depth=3):
Expand Down Expand Up @@ -164,10 +165,6 @@ def proccess_qresults(result, qubits, complete=True):
pdf.sort_values(["Int_lsb"], inplace=True)
return pdf





def solving_circuit(qlm_circuit, nqubit, qlm_qpu, reverse=True):
"""
Solving a complete qlm circuit
Expand Down Expand Up @@ -208,6 +205,49 @@ def solving_circuit(qlm_circuit, nqubit, qlm_qpu, reverse=True):
# mps_state = state.reshape(tuple(2 for i in range(nqubit)))
return pdf_state

def ansatz_selector(ansatz, **kwargs):
"""
Function for selecting an ansatz
Parameters
----------
ansatz : text
The desired ansatz
kwargs : keyword arguments
Different keyword arguments for configurin the ansazt, like
nqubits or depth
Returns
_______
circuit : Atos myqlm circuit
The atos myqlm circuit implementation of the input ansatz
"""


nqubits = kwargs.get("nqubits")
if nqubits is None:
text = "nqubits can not be none"
raise ValueError(text)
depth = kwargs.get("depth")
if depth is None:
text = "depth can not be none"
raise ValueError(text)

if ansatz == "simple01":
circuit = ansatz_qlm_01(nqubits=nqubits, depth=depth)
if ansatz == "simple02":
circuit = ansatz_qlm_02(nqubits=nqubits, depth=depth)
if ansatz == "lda":
circuit = make_ldca_circ(nqubits, ncycles=depth)
if ansatz == "hwe":
circuit = make_general_hwe_circ(nqubits, n_cycles=depth)
else:
text = "ansatz MUST BE simple01, simple02, lda or hwe"
return circuit


class SolveCircuit:

def __init__(self, qlm_circuit, **kwargs):
Expand Down
213 changes: 213 additions & 0 deletions tnbs/BTC_04_PH/PH/btc_ph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
"""
Complete implementation of the Benchmark Test Case for Parent
Hamiltonian kernel.
Author: Gonzalo Ferro
"""
import logging
import time
import uuid
import sys
import numpy as np
import pandas as pd
from qat.core import Observable, Term

sys.path.append("../")
from PH.parent_hamiltonian import PH
from PH.ansatzes import SolveCircuit, ansatz_selector

logging.basicConfig(
format='%(asctime)s-%(levelname)s: %(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p',
level=logging.INFO
#level=logging.DEBUG
)
logger = logging.getLogger('__name__')


def get_qpu(qpu=None):
"""
Function for selecting solver.
Parameters
----------
qpu : str
* qlmass: for trying to use QLM as a Service connection to CESGA QLM
* python: for using PyLinalg simulator.
* c: for using CLinalg simulator
* mps: for using mps
Returns
----------
linal_qpu : solver for quantum jobs
"""

if qpu is None:
raise ValueError(
"qpu CAN NOT BE NONE. Please select one of the three" +
" following options: qlmass, python, c")
if qpu == "qlmass":
try:
from qlmaas.qpus import LinAlg
linalg_qpu = LinAlg()
except (ImportError, OSError) as exception:
raise ImportError(
"Problem Using QLMaaS. Please create config file" +
"or use mylm solver") from exception
elif qpu == "mps":
try:
from qlmaas.qpus import MPS
linalg_qpu = MPS(lnnize=True)
except (ImportError, OSError) as exception:
raise ImportError(
"Problem Using QLMaaS. Please create config file" +
"or use mylm solver") from exception
elif qpu == "python":
from qat.qpus import PyLinalg
linalg_qpu = PyLinalg()
elif qpu == "c":
from qat.qpus import CLinalg
linalg_qpu = CLinalg()
elif qpu == "default":
from qat.qpus import get_default_qpu
linalg_qpu = get_default_qpu()
else:
raise ValueError(
"Invalid value for qpu. Please select one of the three "+
"following options: qlmass, python, c")
#print("Following qpu will be used: {}".format(linalg_qpu))
return linalg_qpu


def ph_btc(**kwargs):
ansatz = kwargs.get("ansatz", None)
nqubits = kwargs.get("nqubits", None)
depth = kwargs.get("depth", None)
qpu_ansatz = kwargs.get("qpu_ansatz", None)
parameters = kwargs.get("parameters", None)
qpu_ph = kwargs.get("qpu_ph", None)
nb_shots = kwargs.get("nb_shots", 0)
save = kwargs.get("save", False)
folder = kwargs.get("folder", './')
ansatz_conf = {
"nqubits": nqubits, "depth": depth
}
ansatz_circuit = ansatz_selector(ansatz, **ansatz_conf)
solve_conf = {
"qpu" : qpu_ansatz, "parameters": parameters

}
sol_ansatz = SolveCircuit(ansatz_circuit, **solve_conf)
logger.info('Solving ansatz')
tick = time.time()
sol_ansatz.run()
# Now the circuit need to have the parameters
ansatz_circuit = sol_ansatz.circuit
amplitudes = list(sol_ansatz.state['Amplitude'])
ph_ansatz = PH(amplitudes)
logger.info('Computing Local Parent Hamiltonian')
ph_ansatz.local_ph()
pauli_coefs = ph_ansatz.pauli_coeficients
pauli_strings = ph_ansatz.pauli_matrices
affected_qubits = ph_ansatz.qubits_list
pauli_df = pd.DataFrame(
[pauli_coefs, pauli_strings, affected_qubits],
index=['PauliCoefficients', 'PauliStrings', 'Qbits']).T
angles = [k for k, v in sol_ansatz.parameters.items()]
values = [v for k, v in sol_ansatz.parameters.items()]
parameter_ansatz = pd.DataFrame(
[angles, values],
index=['key', 'value']).T
filename_base = str(uuid.uuid1())
if save:
pauli_df.to_csv(folder + filename_base+'_pauli.csv', sep=';')
parameter_ansatz.to_csv(
folder + filename_base+'_parameters.csv', sep=';')
# Creating Pauli Terms
terms = [Term(coef, ps, qb) for coef, ps, qb in \
zip(pauli_coefs, pauli_strings, affected_qubits)]
# Creates the atos myqlm observable
observable = Observable(nqbits=nqubits, pauli_terms=terms)
# Creates the job
job_ansatz = ansatz_circuit.to_job(
'OBS', observable=observable, nbshots=nb_shots)
logger.info('Execution Local Parent Hamiltonian')
tick_q = time.time()
# Quantum Routine
gse = qpu_ph.submit(job_ansatz)
gse = gse.value
tock = time.time()
quantum_time = tock - tick_q
elapsed_time = tock - tick
text = ['gse', 'elapsed_time', 'quantum_time']
res = pd.DataFrame(
[gse, elapsed_time, quantum_time],
index=text
).T
if save:
res.to_csv(folder + filename_base+'_result.csv', sep=';')
return res

if __name__ == "__main__":
import argparse

parser = argparse.ArgumentParser()

parser.add_argument(
"-nqubits",
dest="nqubits",
type=int,
help="Number of qbits for the ansatz.",
default=None,
)
parser.add_argument(
"-depth",
dest="depth",
type=int,
help="Depth for ansatz.",
default=None,
)
parser.add_argument(
"-ansatz",
dest="ansatz",
type=str,
help="Ansatz type: simple01, simple02, lda or hwe.",
default=None,
)
#QPU argument
parser.add_argument(
"-qpu_ansatz",
dest="qpu_ansatz",
type=str,
default=None,
help="QPU for ansatz simulation: [qlmass, python, c, mps]",
)
parser.add_argument(
"-qpu_ph",
dest="qpu_ph",
type=str,
default=None,
help="QPU for parent hamiltonian simulation: [qlmass, python, c]",
)
parser.add_argument(
"--save",
dest="save",
default=False,
action="store_true",
help="For storing results",
)
parser.add_argument(
"-folder",
dest="folder",
type=str,
default="./",
help="Path for stroing results",
)
args = parser.parse_args()
print(args)
dict_ph = vars(args)
dict_ph.update({"qpu_ansatz": get_qpu(dict_ph['qpu_ansatz'])})
dict_ph.update({"qpu_ph": get_qpu(dict_ph['qpu_ph'])})
print(dict_ph)
ph_btc(**dict_ph)

0 comments on commit 6f69d36

Please sign in to comment.