Is GHZ feasible on qpu:ascella?

I am building up my understanding of running the GHZ circuit on qpu:ascella.

The attached code runs on a noisy simulator. I increase the noise level to observe how the probability of measuring the 000 or 111 states is affected. However, the results do not look very promising.

With the following configuration (very low noise level):

source = pcvl.Source(emission_probability=0.95, multiphoton_component=0.01)

I observe a reasonable fidelity: n0+n1/ns=0.675. Acceptable.

However, with this setup:

source = pcvl.Source(emission_probability=0.65, multiphoton_component=0.01)

The fidelity drops to n0+n1/ns=0.080

For qpu:ascella, I believe this is the appropriate configuration:

source = pcvl.Source(emission_probability=0.25, multiphoton_component=0.01)

In this case, the fidelity becomes n0+n1/ns=0.002, meaning only about 2 out of 1000 successful measurements would yield the GHZ state on qpu:ascella.

Is my circuit correct? Is my noise model too harsh? Could I make any improvements to increase the probability of measuring the 3-qubit GHZ state on the HW?

Thank you for your guidance and insights.
Jan

# cat noisy_ghz.py
import perceval as pcvl
from perceval.algorithm import Sampler
import numpy as np
print('perceval ver:',pcvl.__version__)

cnot = pcvl.catalog["heralded cnot"].build_processor()

source = pcvl.Source(emission_probability=0.25, multiphoton_component=0.01)
#source=None  # activate to disable noise

num_qubit=3  # <=== change  GHZ state size here
num_mode=2*num_qubit
min_photon=num_qubit + 2 * (num_qubit - 1)

# Set detected photons filter and circuit
proc = pcvl.Processor("SLOS",num_mode,source)
proc.min_detected_photons_filter(num_photon)
proc.add(0, pcvl.BS.H())
for j in range(num_qubit-1):
    proc.add(2*j, cnot)
pcvl.pdisplay(proc)

# Run the simulation
shots = 10_000
sampler = Sampler(proc, max_shots_per_call=shots)    

st0=pcvl.BasicState([1,0]*num_qubit) # all qubits in 0-state
st1=pcvl.BasicState([0,1]*num_qubit) # all qubits in 1-state
proc.with_input(st0 )
resD=sampler.sample_count()  
photC=resD['results'] # number of photons in each mode.

n0=0
n1=0
k=0
for phSt, count in photC.items():
    tag=' '
    if phSt==st0:  
        n0=count
        tag='*'
    if phSt==st1:  
        n1=count
        tag='*'
    if k<15 or tag=='*':
        print('%s meas phSt %s,  count %d'%(tag,phSt,count))
    else: print('.',end='')
    k+=1

print('\ntransmission: %.2e  num final states: %d'%(resD['physical_perf'], k))
print('0s prob: %.4f'% (n0/shots)) 
print('1s prob: %.4f'% (n1/shots))
print(' num sigma: |no-n1|/sqrt(n0+n1)=%.3f '%( abs(n0-n1)/np.sqrt(n0+n1))) 
print('asymmetry: n0-n1/n0+n1 =%.4f'%( (n0-n1)/(n0+n1)))
print('fidelity: n0+n1/ns=%.3f'%((n0+n1)/shots))

Hello,

The problem here is that each heralded cnots brings two added photons for the heralds. As such, your min_detected_photons_filter is not high enough. It should be num_qubit + 2 * (num_qubit - 1).
This way, you will find only states with 3 photons at the end.

Running this on your provided code (with emission_probability=0.25, multiphoton_component=0.01) gives a fidelity of 0.84.

Also, if you are planning to use this for more than a learning process, you should use a converter from another library to get your processor, as it will also use postprocessed cnots whenever it can. They are less sensitive to noise since they don’t use auxiliary photons for the heralds. Doing this on your script increases the fidelity to 0.92. Due to a bug that will be fixed in the next perceval version, you should set manually the min_detected_photons_filter, else you could get imprecise results.

Regards

Hi Aubaert,

I am very interested in running as large a circuit as practical on your hardware. As mentioned earlier, you are the only open provider of a photonic QPU I could find worldwide.

I increased the minimum photon threshold as you suggested and observed much better results. (I have updated my initial code, so the improved version is now available online for others.)

Could you please point me to a tutorial or class where I can learn how to add this ‘converter’ to my code and understand its functionality?

Additionally, after this fix giving me high fidelity in preparing a 3-qubit GHZ state, I observed the transmission to be 7e-5. Does this imply that if I request 100 successful 3-qubit GHZ events, the real hardware would need to initiate approximately 140e6 2-photon events?
If that is the case, would it be feasible to request this many shots on qpu:ascella?

Could you also guide me on how to estimate the transmission from the properties of the components of 3q GHZ circuit?
Would this logic be accurate:

  • 3 qubit initial state → 6 modes → perf = 0.06^3
  • 2 Knill CNOT → success = (2/27)²
  • Total transmission = 0.06^3 * (2/27)² =1e-6

Is my estimate close enough to reported fidelity of 0.7e-6?

Thank you for your guidance and support. If I’m using incorrect names, please correct me.

Best regards,
Jan

Hello,

You can find the documentation for the converter here Decomposing gate-based circuits: qiskit and myQLM — perceval v0.12 documentation.

Beware that there is a bug in the current version of perceval (0.12.1) that makes the postselection wrong when the converter creates several postselected cnots. You can fix it manually by calling proc.clear_postselection() then proc.set_postselection(PostSelect("[0, 1] == 1 & ...")). The post selection string must be all [2k, 2k+1] == 1 for k in range(n_qubits), meaning you want exactly one photon in each dual rail (so you end up with a qubit state). This will be fixed in the next version.

For the performances, it’s a bit more complicated than that if there is g2 and indistinguishability like on ascella, but you can estimate it by forgetting these. If you only consider the imperfect brightness, then the probability of having n photons is brightness ** n (the number of modes doesn’t change anything here), in the case of Ascella, 0.05^3 for postprocessed cnots, or 0.05^7 for heralded cnots. Then you indeed have to take into account the success rate of cnots, so (1/9)^2 for the postprocessed cnots, or (2/27)^2 for the heralded cnots. In the end, the probability to have a success is

  • for postprocessed cnots: 0.05^3 * (1/9)^2 = 1.5e-6
  • for heralded cnots: 0.05^7 * (2/27)^2 = 4.3e-12

Considering that the clock rate (number of photons produced per second) is 80 MHz, the time needed to get k samples would then be t = k * n / (success_rate * clock_rate), so for k = 100 and post selected cnots, it would be 2.4 seconds. For heralded cnots, it would be 2e6 seconds (so too much).

Now, for the number of shots needed, we only count events that have at least 1 photon as a shot. Thus, the probability that an event is a shot is 1 - (1 - brightness)^n. To estimate the number of shots needed, you can divide this probability by the success probability.

  • for postprocessed cnots, it would be 9.2e4 shots.
  • for heralded cnots, it would be 7.0e10 shots.

I hope this will help you,

Regards,

EDIT: we just release Perceval 0.12.2 that fixes the conversion problem I mentioned earlier, so you don’t have to fix it manually.