mirror of https://github.com/intel/intel-qs.git
205 lines
6.9 KiB
Python
205 lines
6.9 KiB
Python
'''Example of Python script that uses MPI to run simulations of noisy systems.
|
|
The noise is described using the chi-matrix of standard phenomenological
|
|
models like dephasing channel, depolarizing channel, and amplitude damping.
|
|
|
|
See iPython notebook 'noise_via_chi_matrix_example.ipynb' for a description
|
|
of the channels.
|
|
'''
|
|
|
|
import sys
|
|
sys.path.insert(0, '../build/lib')
|
|
import intelqs_py as iqs # Import IQS library
|
|
import numpy as np # Import NumPy library
|
|
import pandas as pd # Import library to store results in dataframes
|
|
|
|
# Name of files and directories.
|
|
data_dir = './noise_via_chi_matrix/'
|
|
file_df1 = data_dir + 'example_TYPE-channel_qQUBITS.pkl'
|
|
|
|
# Parameters of the simulation.
|
|
num_ensemble_states = 100
|
|
num_time_steps = 20
|
|
p_for_channel = 0.1
|
|
|
|
def get_chi_matrix(channel_type, parameter=0.01):
|
|
'''Define the chi-matrix associated to the channel'''
|
|
p=parameter
|
|
chi = iqs.CM4x4()
|
|
if channel_type == 'depolarizing':
|
|
chi[0,0] = 1-p
|
|
chi[1,1] = p/3
|
|
chi[2,2] = p/3
|
|
chi[3,3] = p/3
|
|
elif channel_type == 'dephasing':
|
|
chi[0,0] = 1-p
|
|
chi[3,3] = p
|
|
elif channel_type == 'amplitude-damping':
|
|
chi[0,0] = (1+np.sqrt(1-p))**2
|
|
chi[0,3] = p
|
|
chi[3,0] = p
|
|
chi[3,3] = (1-np.sqrt(1-p))**2
|
|
chi[1,1] = p**2
|
|
chi[1,2] = -1j * p**2
|
|
chi[2,1] = +1j * p**2
|
|
chi[2,2] = p**2
|
|
else:
|
|
print('ERROR: unrecognized channel')
|
|
chi.SolveEigenSystem()
|
|
return chi
|
|
|
|
|
|
def run_circuit(num_qubits):
|
|
reg = iqs.QubitRegister(num_qubits, 'base', 0, 0)
|
|
for i in range(num_qubits):
|
|
reg.ApplyHadamard(i)
|
|
reg.ApplyRotationZ(i, np.pi/3)
|
|
return reg
|
|
|
|
#------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
iqs.EnvInit()
|
|
myrank = iqs.MPIEnvironment.GetRank()
|
|
if len(sys.argv) <= 1:
|
|
if myrank==0:
|
|
print('Usage: {} <channel_type>'.format(sys.argv[0]))
|
|
iqs.EnvFinalize()
|
|
sys.exit(0)
|
|
|
|
channel_type = str(sys.argv[1])
|
|
# Choices of the channel are:
|
|
if channel_type not in ['depolarizing', 'dephasing', 'amplitude-damping']:
|
|
if myrank==0:
|
|
print('Wrong type of channel.\nAvailable channels are: dephasing, depolarizing, amplitude-damping.')
|
|
iqs.EnvFinalize()
|
|
sys.exit(0)
|
|
|
|
# Exit from dummy processes.
|
|
if iqs.MPIEnvironment.IsUsefulRank()==False:
|
|
iqs.EnvFinalize()
|
|
exit()
|
|
|
|
# The simulation of a N-qubit system cannot be divided in more than 2^(N-1) ranks.
|
|
num_qubits = 4 # number of qubits
|
|
if iqs.MPIEnvironment.GetStateSize()>2**(num_qubits-1) or num_qubits<1:
|
|
if iqs.MPIEnvironment.GetRank()==0:
|
|
print("No more than 2^(N-1) useful ranks for a N-qubit state.")
|
|
iqs.EnvFinalize()
|
|
exit()
|
|
|
|
# Prapare the initial state
|
|
index = 1*0 + 1*2 + 0*4 + 1*8
|
|
psi = iqs.QubitRegister(num_qubits, 'base', index, 0) # |psi> = |1010>
|
|
psi.ApplyHadamard(2) # |psi> = |1+10>
|
|
psi.ApplyHadamard(3) # |psi> = |-+10>
|
|
|
|
# Associate a random-number-generator to the state
|
|
rng = iqs.RandomNumberGenerator()
|
|
rng_seed = 7777
|
|
rng.SetSeedStreamPtrs( rng_seed )
|
|
|
|
# Get the chi-matrix of the channel
|
|
chi = get_chi_matrix(channel_type, p_for_channel)
|
|
if myrank==0:
|
|
chi.Print(True)
|
|
|
|
# parameter of the evolution
|
|
collective_list = []
|
|
for s in range(num_ensemble_states):
|
|
if s%20==0 and myrank==0:
|
|
print("-- state", s, "of the ensemble")
|
|
psi_s = iqs.QubitRegister(psi)
|
|
psi_s.SetRngPtr(rng)
|
|
for t in range(0,num_time_steps):
|
|
sq_overlap = np.absolute(psi_s.ComputeOverlap(psi))**2 # the overlap is computed as if at the begin of time step t
|
|
if sq_overlap > 1:
|
|
if myrank==0:
|
|
print(s, t, sq_overlap)
|
|
psi_s.Print('large overlap?')
|
|
if psi_s.GetOverallSignOfChannels() < 0:
|
|
sq_overlap = sq_overlap * (-1)
|
|
if myrank==0:
|
|
print('possible error: overall negative sign')
|
|
for q in range(num_qubits):
|
|
psi_s.ApplyChannel(q, chi) # then the channel is implemented
|
|
collective_list.append([s, t, sq_overlap])
|
|
df = pd.DataFrame(collective_list, columns =['s', 't', 'sq_overlap'])
|
|
filename = file_df1.replace('TYPE', channel_type)
|
|
filename = filename.replace('QUBITS', str(num_qubits))
|
|
if myrank==0:
|
|
df.to_pickle(filename), '\n'
|
|
print('data saved in file ', filename, '\n')
|
|
|
|
iqs.MPIEnvironment.Barrier()
|
|
print('Computation completed at rank {}'.format(myrank))
|
|
|
|
iqs.EnvFinalize()
|
|
|
|
# SAMPLE RUNS:
|
|
|
|
## Single-Process:
|
|
'''
|
|
python chi_matrix_with_mpi.py dephasing
|
|
[|0>: 0] world_rank: 0 , state_rank: 0 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 1 , threads/rank: 112 --useful
|
|
chi_matrix :
|
|
(0.9,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0.1,0)
|
|
eigenvalues :
|
|
(0,0) (0,0) (0.1,0) (0.9,0)
|
|
eigenprobs :
|
|
0 0 0.1 0.9
|
|
eigenvector 0 :
|
|
(0,0) (1,0) (0,0) (0,0)
|
|
eigenvector 1 :
|
|
(0,0) (0,0) (1,0) (0,0)
|
|
eigenvector 2 :
|
|
(0,0) (0,0) (0,0) (1,0)
|
|
eigenvector 3 :
|
|
(1,0) (0,0) (0,0) (0,0)
|
|
-- state 0 of the ensemble
|
|
-- state 20 of the ensemble
|
|
-- state 40 of the ensemble
|
|
-- state 60 of the ensemble
|
|
-- state 80 of the ensemble
|
|
data saved in file ./noise_via_chi_matrix/example_dephasing-channel_q4.pkl
|
|
'''
|
|
|
|
## Multi-Process:
|
|
'''
|
|
mpiexec -n 4 python chi_matrix_with_mpi.py dephasing
|
|
[|s0>: 0] world_rank: 0 , state_rank: 0 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 4 , threads/rank: 28 --useful
|
|
[|s0>: 1] world_rank: 1 , state_rank: 1 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 4 , threads/rank: 28 --useful
|
|
[|s0>: 2] world_rank: 2 , state_rank: 2 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 4 , threads/rank: 28 --useful
|
|
[|s0>: 3] world_rank: 3 , state_rank: 3 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 4 , threads/rank: 28 --useful
|
|
chi_matrix :
|
|
(0.9,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0,0)
|
|
(0,0) (0,0) (0,0) (0.1,0)
|
|
eigenvalues :
|
|
(0,0) (0,0) (0.1,0) (0.9,0)
|
|
eigenprobs :
|
|
0 0 0.1 0.9
|
|
eigenvector 0 :
|
|
(0,0) (1,0) (0,0) (0,0)
|
|
eigenvector 1 :
|
|
(0,0) (0,0) (1,0) (0,0)
|
|
eigenvector 2 :
|
|
(0,0) (0,0) (0,0) (1,0)
|
|
eigenvector 3 :
|
|
(1,0) (0,0) (0,0) (0,0)
|
|
-- state 0 of the ensemble
|
|
-- state 20 of the ensemble
|
|
-- state 40 of the ensemble
|
|
-- state 60 of the ensemble
|
|
-- state 80 of the ensemble
|
|
data saved in file ./noise_via_chi_matrix/example_dephasing-channel_q4.pkl
|
|
|
|
Computation completed at rank 0
|
|
Computation completed at rank 1
|
|
Computation completed at rank 2
|
|
Computation completed at rank 3
|
|
'''
|