1. Advanced Application Techniques¶
1.1 Experiment Collection Management¶
To provide a reasonable classification and management of experiments, the quantum computing cloud platform introduces the concept of experiment collection and offers experiment collection management.
You can place experimental circuits in a designated collection when submitting them, for later management and viewing.
Note:
You need to create an experiment collection first or pass existing collection information to subsequent experiments.
Experiment collections cannot have the same name, and within the same collection, experiment names cannot be duplicated.
The display performance of the cloud platform website on the web end is pending optimization, please bear with us.
The specific method for creating experiment collections is as follows:
from ezQgd import *
account = Account(login_key='opecT+SO+QFjLXREUU2f8paSJNtTytPPV8Dbbd2T8Zg=', machine_name='gd_qc1')
create_res = account.create_experiment('Machine LearningB')
if create_res == 0:
print('Failed to Create Experiment Collection')
else :
print('Successfully Created Experiment Collection,ID=', create_res)
lab_id = create_res
#The experiment collection ID is recommended to be retained for future use.
Alternatively, you can directly use an existing experiment ID.
lab_id=create_res #Your experimentId
#The web-based method to query the experiment collection ID is as follows: In the 'My Experiment Collections' page, click on the collection you want to view, and observe the information in the browser's address bar,eg.
#https://quantumctek-cloud.com/expList.html?experimentId=1639487661985239040
#The parameters following 'experimentId' are the experiment collection ID
The procedure for submitting a quantum circuit to a designated experiment collection is as follows:
qcis_circuit = '''
H Q6
X Q0
H Q0
CZ Q6 Q0
H Q0
M Q6
M Q0
'''
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="GPT4-a123")
#For a single experiment submission, you can manually input the above parameters. If you wish to design an automated program, the 'version' parameter value can be pre-generated using methods such as counting.
#All other processes follow the standard procedure.
print(query_id)
1.2 Switch Quantum Computer¶
In most cases, we will use the variable name 'computer_type' to represent the desired quantum computer model, and then when calling 'account,' directly set the quantum computer.
For programs that have already been developed and validated using a particular machine, such as a response machine, you only need to modify variable names to quickly adapt to the subsequent computer usage scenarios.
from ezQgd import *
login_key='opecT+SO+QFjLXREUU2f8paSJNtTytPPV8Dbbd2T8Zg='
machine_name = 'gd_test'
account = Account(login_key=login_key, machine_name=machine_name)
#Set the user SDK key, choose a quantum computer, and create an instance.
print(account.machine_name)
But in some special cases, such as when you want to quickly submit the same experiment segment to two different machines for comparison within a single program, you can utilize the quantum computer's configuration feature.
machine_name = 'gd_test'
account = Account(login_key=login_key)#Quantum computer not configured
print(account.machine_name)
#View the currently selected quantum computer
account.set_machine(machine_name)
#When switching quantum computers, please note that the final submitted program must adhere to the quantum computer's topology constraints, or else you may encounter errors during experiment submission.
print(account.machine_name)
#To check whether the quantum computer settings have taken effect
1.3 Running the same circuit multiple times¶
Please note that the quantum computing cloud platform only accepts circuits with fixed parameters. Even for circuits with parameters, at the current stage, these parameters are pre-set to specific values before submission. Therefore, when running the same circuit multiple times, the circuit structure and parameter values are all explicitly fixed.
This requirement is often used for comparing specific circuit results or for direct applications based on circuit results.
Based on the explanation in the previous section, it is evident that submitting circuits step by step can obtain the ID of the circuit itself, which can be saved. During runtime, you can simply provide this ID to execute the circuit. If you need to run the circuit multiple times, you only need to submit the execution of that ID multiple times.
#Continuing from the previous example program
saved_exp_id=exp_id
#saved_exp_id='ustc3142744691105312700000005360'
result_list=[]
for i in range(2) :
query_id=account.run_experiment(exp_id=saved_exp_id, num_shots=1000)#The 'num_shots' parameter in the above 'submit_job' is set to the default value of 12000.
result=account.query_experiment(query_id, max_wait_time=360000)
result_list.append(result)
print(result_list)
1.4 Circuit parameterization¶
While it's possible to achieve arbitrary gate operations using a complete set of standard gates, for classical data inputs, it's preferable to directly pass them into the quantum program rather than redesigning the circuit based on parameters.
So, we have specifically added the parameter passing function 'assign_parameters' directly in 'submit_job.' Users can also use this function during the circuit preparation phase to pass parameters into the circuit.
Utilizing circuit parameterization and batch submission can significantly speed up batch experiments with fixed circuits but different parameters. For more details, please refer to the batch experiment submission.
#In the circuit, pre-set {x} represents the parameter to be passed
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#It's important to note that 'assign_parameters' is primarily used in 'submit_job,' so the parameter format is mainly in the form of lists. Even when passing a circuit and its associated parameters and values, they should be in list format.
values=[[0.1,0.2]]
#Please note that the first parameter of 'assign_parameters' is 'circuits,' with an 's' at the end, indicating a plural form. Be sure to pass a list into it.
qcis_circuit=account.assign_parameters(circuits=[qcis_circuit], parameters=[['N1','N2']], values=values)
print(qcis_circuit)
#Please note that at this point, 'qcis_circuit' has been included as a parameter, becoming a specific circuit without dynamic parameters.
#Alternatively, you can directly use the 'submit_job' function and pass the parameters.
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2]]
query_id = account.submit_job(circuit=[qcis_circuit],parameters=[['N1','N2']], values=values)
print(query_id)
The above example of passing parameters doesn't serve much purpose, it's for demonstration only.
When designing heterogeneous programs, this parameter passing will be utilized, allowing 'values' to be calculated in real-time based on dynamic data, resulting in more robust parameter updates.
Because batch submission of circuits is currently supported, the input circuits are in list format, and their corresponding parameters are in list[list] format. Therefore, please pay attention to the parameter format.
1.5 Decomposition of Experiment Submission Actions¶
The 'submit_job()' function is essentially a function that encapsulates multiple actions together. If there are specific requirements, you can execute submission actions separately or redesign your own submission function.
The actions within the current submission function include:
- assign_parameters(circuit, parameters, values)
Quickly input the variable parameters of the quantum circuit to generate the final quantum circuit.
- save_experiment(lab_id, exp_data, name='detailtest', language='qcis')
Saving the quantum circuit to the cloud platform for later retrieval and returning the experiment circuit ID. The 'name' is equivalent to the 'version' variable in 'submit_job'.
- run_experiment(exp_id, num_shots=12000)
Run the circuit with the specified experiment ID.
So, a 'submit_job()' submission can be equated to the following actions.
#In the circuit, the pre-set {x} represents the parameters to be passed
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#Please note that 'assign_parameters' is primarily used within 'submit_job,' so the parameter format is mainly in the form of lists. Even if you are passing a circuit and its associated parameters and values, you should use a list format.
values=[[0.1,0.2]]
from ezQgd import *
login_key='opecT+SO+QFjLXREUU2f8paSJNtTytPPV8Dbbd2T8Zg='
machine_name = 'gd_test'
account = Account(login_key=login_key, machine_name=machine_name)
#Set the user SDK key, select a quantum computer, and create an instance.
lab_id='3abe799a8e5941f884d27dec96f3e00b'
#query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="Artificial Intelligence a1234")
#The previous 'submit_job' is equivalent to the following actions:
#Please note that the first parameter of 'assign_parameters' is 'circuits,' with an 's' at the end, indicating a plural form. You must pass a list into it.
qcis_circuit=account.assign_parameters(circuits=[qcis_circuit], parameters=[['N1','N2']], values=values)
print(qcis_circuit)
#Note that at this point, 'qcis_circuit' has already been included as a parameter, becoming a specific circuit without dynamic parameters.
exp_id=account.save_experiment(lab_id=lab_id, exp_data=qcis_circuit[0], version="Artificial Intelligence a12345")#The 'language' parameter cannot be externally input in the 'submit_job' function. Currently, this value only supports 'qcis.'
print(exp_id)
query_id=account.run_experiment(exp_id=exp_id, num_shots=12000)#The 'num_shots' parameter in the above 'submit_job' uses the default value of 12000.
print(query_id)
1.6 Probability Statistics¶
To save bandwidth and allow quantum computing-related services to focus more on quantum computing tasks, when measuring more than 15 qubits, the quantum computer no longer performs probability statistics and readout correction for users, and users need to handle it themselves.
We provide basic probability statistics functions, which can be called as follows:
qcis_circuit = '''
H Q6
X Q0
H Q0
CZ Q6 Q0
H Q0
M Q6
M Q0
'''
from ezQgd import *
account = Account(login_key='opecT+SO+QFjLXREUU2f8paSJNtTytPPV8Dbbd2T8Zg=', machine_name='gd_qc1')
query_id = account.submit_job(qcis_circuit)
print(query_id)
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
print(result[0]['probability'])
print(result[0]['probability'])
probability_whole=account.readout_data_to_state_probabilities_whole(result[0])
print(probability_whole)
#The above functions perform a complete space-wide statistics of results, and if there are many measured qubits, the programming environment will require a vast amount of memory.
probability_part=account.readout_data_to_state_probabilities_part(result[0])
print(probability_part)
#The above functions only perform statistics on existing results, and outcomes with a probability of 0 will not be included, which helps save storage space. Additionally, the first type of complete statistics consumes a significant amount of memory.
1.7 Readout Correction¶
Today's quantum computers have reliability issues in multiple stages, and readout correction is required when using statistical results.
When the number of measured qubits is 15 or less, the returned probability results have already undergone readout correction.
#Readout correction requires using the experimental results and the quantum computer parameter file as inputs for computation.
#If the computer parameter file is not provided, the current quantum computer parameters are used.
#When saving experiment results, you can obtain them through the 'download_config()' function.
probability_cali=account.probability_calibration(result[0])
print(probability_cali)
#This readout correction is a correction of the statistical probabilities and is not achieved through probability resampling.
#If resampling is required for data correction, we kindly ask users to design and implement it themselves.
probability_cor=account.probability_correction(probability_cali)
print(probability_cor)
1.8 Batch Experiment Submission¶
To reduce the significant delay caused by batch experiment submissions, we have implemented various ways of running experiments in bulk. The first one provided is batch experiment submission with minimal changes to the original process.
This batch experiment submission is primarily designed for situations where users have essentially identical circuits, especially with the same measured qubits, and only variations in parameter inputs are allowed. (Very important)
In this mode, users can run multiple circuits sequentially on the quantum computer with a single submission action.
The focus of batch experiment submission is on efficiency, so we only provide users with raw experimental data and the most basic SDK functions. How to efficiently utilize these results is up to the users to handle on their own. We do not currently provide advanced functions to streamline data processing, in order to maintain efficiency.
When users encounter any exceptions or feel that something is not as expected while using this feature, please contact us as soon as possible for further investigation and clarification.
Some of the limitations of this feature can be found in the function documentation. These limitations mainly include constraints on the number of circuits submitted simultaneously, the number of shots, the measured qubits, etc. Additionally, when querying results, the function allows a maximum of 50 circuits to be queried at once. If you submit more than 50 circuits in a single submission, please manage your queries by grouping them.
from ezQgd import *
account = Account(login_key='opecT+SO+QFjLXREUU2f8paSJNtTytPPV8Dbbd2T8Zg=', machine_name='gd_qc1')
qcis_circuit_A = '''
Rx Q0 0
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
qcis_circuit_B = '''
Rx Q0 0.1
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
qcis_circuit = [qcis_circuit_A, qcis_circuit_B]*10
#Combine all the required circuits into a single list.
#Note: This mode is effective only when the measured qubits and their measurement order are the same. In other situations, you can submit, but we do not guarantee the correctness of the results.
#Note: In this mode, the points consumed are calculated as the total number of circuits * points deducted per single circuit, so please submit sensibly.
print(qcis_circuit)
#All other actions remain unchanged.
#But please note that the points consumed are calculated based on the number of circuits in the list.
query_id = account.submit_job(circuit=qcis_circuit,num_shots=1000)
print(query_id)
#Note that when batch submitting, the 'query_id' is also a list, allowing you to query experiment IDs in the specified order.
if query_id:
results=account.query_experiment(query_id, max_wait_time=360000)
#The result query function supports a maximum of 50 circuit results to be queried simultaneously. So, if you previously submitted a larger batch, when querying results, users should split the list of IDs into segments of 50 for querying.
#The experiment results are in the form of a list of individual results, just as with a single result.
#Users should take note that, in this mode, the waiting time for result retrieval may significantly increase compared to the time it takes for a single submission multiplied by the total number of submissions.
#In order to optimize batch submission mode, statistical results are not calculated on the physical machine; the probability section is left empty, and users need to process it on their own local machines.
#So, make sure to save the current computer parameters promptly for later result correction.
res=account.download_config()
p1 = []
for query_res in results:
# Experiment result transformation, probability conversion, and readout correction.
# results = account.readout_data_to_state_probabilities_whole(query_res)
prob = account.probability_calibration(query_res, res)
prob = account.probability_correction(prob)
p1.append(prob)
print(p1)
#Processing the results for the new round of circuits.
else :
#The experiment did not run successfully and requires subsequent resubmission or other handling.
print("The experiment encountered an abnormality during execution and requires resubmission or reexecution.")
Using circuit parameterization and batch submission can significantly accelerate fixed-circuit experiments with varying parameters.
#Below is an example that combines circuit parameterization and batch submission.
#In the circuit, pre-set {x} represents the parameters to be passed.
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2],[0.2,0.1]]
qcis_circuit=account.assign_parameters(circuits=[qcis_circuit]*2, parameters=[['N1','N2']]*2, values=values)
print(qcis_circuit)
#Note that at this point, 'qcis_circuit' has already been included as a parameter, becoming a specific circuit without dynamic parameters.
#Alternatively, you can directly use the 'submit_job' function and pass the parameters.
qcis_circuit = '''
RX Q0 {N1}
RX Q6 {N2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
values=[[0.1,0.2],[0.2,0.1]]
query_id = account.submit_job(circuit=[qcis_circuit]*2,parameters=[['N1','N2']]*2, values=values, num_shots=1000)
print(query_id)
p1 = []
if query_id:
#When 'query_id' exceeds 50 items, it needs to be split into groups of 50 for retrieval. Therefore, submitting in batches of 50 is more efficient.
result=account.query_experiment(query_id, max_wait_time=360000)
for query_res in result:
# Experiment result transformation, probability conversion, readout correction.
# results = account.readout_data_to_state_probabilities_whole(query_res)
prob = account.probability_calibration(query_res)
prob = account.probability_correction(prob)
p1.append(prob)
print(p1)