eclipse-qrisp / Qrisp

Qrisp - a framework for high-level programming of Quantum computers
https://www.qrisp.eu/
Eclipse Public License 2.0
83 stars 23 forks source link

ConnectionError when running istances of Shor's algorithm #36

Open diehoq opened 6 months ago

diehoq commented 6 months ago

I'm getting disconnected when I try to run jobs for a longer time than what I usually do. Could somebody tell me where does the problem come from and if there is already a solution for that, apart from exporting the circuit into QASM and run it independently from Qrisp?

The issue is generated by multiple runs of the following code:

def get_r_candidates(approx):
    rationals = continued_fraction_convergents(continued_fraction_iterator(Rational(approx)))
    return [rat.q for rat in rationals]

def find_order(a, N): 
    qg = QuantumModulus(N)
    qg[:] = 1
    qpe_res = QuantumFloat(2*qg.size + 1, exponent = -(2*qg.size + 1))
    h(qpe_res)
    x=a
    for i in range(len(qpe_res)):
        with control(qpe_res[i]):
            qg *= x
            x = (x*x)%N
    QFT(qpe_res, inv = True)
    return qpe_res.get_measurement(backend=vrtl_qasm_sim)

def quantum_shor(a,N):
    meas_res = find_order(a,N)
    r_candidates = sum([get_r_candidates(approx) for approx in meas_res.keys()], [])
    for cand in r_candidates:
        if (a**cand)%N == 1:
            r = cand
            break
    else:
        raise Exception("Please sample again")
    if r % 2:
        raise Exception("Please choose another a")
    p = np.gcd(a**(r//2)+1, N)
    q = int(N/p)
    if(p>q):
        return(q,p)
    return(p,q)

for _ in range(10):
    print(quantum_shor(a,N))
Expand Error { "name": "ConnectionError", "message": "('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))", "stack": "--------------------------------------------------------------------------- ConnectionResetError Traceback (most recent call last) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connectionpool.py:791, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw) 790 # Make the request on the HTTPConnection object --> 791 response = self._make_request( 792 conn, 793 method, 794 url, 795 timeout=timeout_obj, 796 body=body, 797 headers=headers, 798 chunked=chunked, 799 retries=retries, 800 response_conn=response_conn, 801 preload_content=preload_content, 802 decode_content=decode_content, 803 **response_kw, 804 ) 806 # Everything went great! File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connectionpool.py:537, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length) 536 try: --> 537 response = conn.getresponse() 538 except (BaseSSLError, OSError) as e: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connection.py:461, in HTTPConnection.getresponse(self) 460 # Get the response from http.client.HTTPConnection --> 461 httplib_response = super().getresponse() 463 try: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:1375, in HTTPConnection.getresponse(self) 1374 try: -> 1375 response.begin() 1376 except ConnectionError: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:318, in HTTPResponse.begin(self) 317 while True: --> 318 version, status, reason = self._read_status() 319 if status != CONTINUE: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:279, in HTTPResponse._read_status(self) 278 def _read_status(self): --> 279 line = str(self.fp.readline(_MAXLINE + 1), \"iso-8859-1\") 280 if len(line) > _MAXLINE: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\socket.py:705, in SocketIO.readinto(self, b) 704 try: --> 705 return self._sock.recv_into(b) 706 except timeout: ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host During handling of the above exception, another exception occurred: ProtocolError Traceback (most recent call last) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\adapters.py:486, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies) 485 try: --> 486 resp = conn.urlopen( 487 method=request.method, 488 url=url, 489 body=request.body, 490 headers=request.headers, 491 redirect=False, 492 assert_same_host=False, 493 preload_content=False, 494 decode_content=False, 495 retries=self.max_retries, 496 timeout=timeout, 497 chunked=chunked, 498 ) 500 except (ProtocolError, OSError) as err: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connectionpool.py:845, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw) 843 new_e = ProtocolError(\"Connection aborted.\", new_e) --> 845 retries = retries.increment( 846 method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2] 847 ) 848 retries.sleep() File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\util\\retry.py:470, in Retry.increment(self, method, url, response, error, _pool, _stacktrace) 469 if read is False or method is None or not self._is_method_retryable(method): --> 470 raise reraise(type(error), error, _stacktrace) 471 elif read is not None: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\util\\util.py:38, in reraise(tp, value, tb) 37 if value.__traceback__ is not tb: ---> 38 raise value.with_traceback(tb) 39 raise value File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connectionpool.py:791, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw) 790 # Make the request on the HTTPConnection object --> 791 response = self._make_request( 792 conn, 793 method, 794 url, 795 timeout=timeout_obj, 796 body=body, 797 headers=headers, 798 chunked=chunked, 799 retries=retries, 800 response_conn=response_conn, 801 preload_content=preload_content, 802 decode_content=decode_content, 803 **response_kw, 804 ) 806 # Everything went great! File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connectionpool.py:537, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length) 536 try: --> 537 response = conn.getresponse() 538 except (BaseSSLError, OSError) as e: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\urllib3\\connection.py:461, in HTTPConnection.getresponse(self) 460 # Get the response from http.client.HTTPConnection --> 461 httplib_response = super().getresponse() 463 try: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:1375, in HTTPConnection.getresponse(self) 1374 try: -> 1375 response.begin() 1376 except ConnectionError: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:318, in HTTPResponse.begin(self) 317 while True: --> 318 version, status, reason = self._read_status() 319 if status != CONTINUE: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\http\\client.py:279, in HTTPResponse._read_status(self) 278 def _read_status(self): --> 279 line = str(self.fp.readline(_MAXLINE + 1), \"iso-8859-1\") 280 if len(line) > _MAXLINE: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\socket.py:705, in SocketIO.readinto(self, b) 704 try: --> 705 return self._sock.recv_into(b) 706 except timeout: ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)) During handling of the above exception, another exception occurred: ConnectionError Traceback (most recent call last) Cell In[50], line 2 1 for _ in range(10): ----> 2 print(quantum_shor(a,N)) Cell In[10], line 2, in quantum_shor(a, N) 1 def quantum_shor(a,N): ----> 2 meas_res = find_order(a,N) 3 r_candidates = sum([get_r_candidates(approx) for approx in meas_res.keys()], []) 4 for cand in r_candidates: Cell In[9], line 12, in find_order(a, N) 10 x = (x*x)%N 11 QFT(qpe_res, inv = True) ---> 12 return qpe_res.get_measurement(backend=vrtl_qasm_sim) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\qrisp\\core\\quantum_variable.py:976, in QuantumVariable.get_measurement(self, plot, backend, shots, compile, compilation_kwargs, subs_dic, circuit_preprocessor, filename, precompiled_qc) 972 qc = qc.transpile() 974 from qrisp.misc import get_measurement_from_qc --> 976 counts = get_measurement_from_qc(qc, self.reg, backend, shots) 978 # Insert outcome labels (if available and hashable) 979 try: File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\qrisp\\misc\\utility.py:1288, in get_measurement_from_qc(qc, qubits, backend, shots) 1285 qc.measure(qubits[i], cl[i]) 1287 # Execute circuit -> 1288 counts = backend.run(qc, shots) 1290 # Remove other measurements outcomes from counts dic 1291 new_counts_dic = {} File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\qrisp\\interface\\backends.py:122, in VirtualBackend.run(self, qc, shots, token) 105 def run(self, qc, shots, token=\"\"): 106 \"\"\" 107 Executes the function run_func specified at object creation. 108 (...) 120 121 \"\"\" --> 122 return super().run(qc, shots) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\qrisp\\interface\\qunicorn\\backend_client.py:126, in BackendClient.run(self, qc, shots) 121 job_running = True 124 while True: --> 126 job_get_response = requests.get(f'{self.api_endpoint}/jobs/{job_id}', json = job_data, verify = False) 128 if job_get_response.status_code != 201: 129 raise Exception(f'Quantum circuit execution failed: {job_get_response.json()[\"message\"]}') File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\api.py:73, in get(url, params, **kwargs) 62 def get(url, params=None, **kwargs): 63 r\"\"\"Sends a GET request. 64 65 :param url: URL for the new :class:`Request` object. (...) 70 :rtype: requests.Response 71 \"\"\" ---> 73 return request(\"get\", url, params=params, **kwargs) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\api.py:59, in request(method, url, **kwargs) 55 # By using the 'with' statement we are sure the session is closed, thus we 56 # avoid leaving sockets open which can trigger a ResourceWarning in some 57 # cases, and look like a memory leak in others. 58 with sessions.Session() as session: ---> 59 return session.request(method=method, url=url, **kwargs) File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\sessions.py:589, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) 584 send_kwargs = { 585 \"timeout\": timeout, 586 \"allow_redirects\": allow_redirects, 587 } 588 send_kwargs.update(settings) --> 589 resp = self.send(prep, **send_kwargs) 591 return resp File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\sessions.py:725, in Session.send(self, request, **kwargs) 722 if allow_redirects: 723 # Redirect resolving generator. 724 gen = self.resolve_redirects(r, request, **kwargs) --> 725 history = [resp for resp in gen] 726 else: 727 history = [] File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\sessions.py:725, in (.0) 722 if allow_redirects: 723 # Redirect resolving generator. 724 gen = self.resolve_redirects(r, request, **kwargs) --> 725 history = [resp for resp in gen] 726 else: 727 history = [] File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\sessions.py:266, in SessionRedirectMixin.resolve_redirects(self, resp, req, stream, timeout, verify, cert, proxies, yield_requests, **adapter_kwargs) 263 yield req 264 else: --> 266 resp = self.send( 267 req, 268 stream=stream, 269 timeout=timeout, 270 verify=verify, 271 cert=cert, 272 proxies=proxies, 273 allow_redirects=False, 274 **adapter_kwargs, 275 ) 277 extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) 279 # extract redirect url, if any, for the next loop File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\sessions.py:703, in Session.send(self, request, **kwargs) 700 start = preferred_clock() 702 # Send the request --> 703 r = adapter.send(request, **kwargs) 705 # Total elapsed time of the request (approximately) 706 elapsed = preferred_clock() - start File c:\\Users\\dpolimen\\anaconda3\\envs\\venvqrisp\\lib\\site-packages\\requests\\adapters.py:501, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies) 486 resp = conn.urlopen( 487 method=request.method, 488 url=url, (...) 497 chunked=chunked, 498 ) 500 except (ProtocolError, OSError) as err: --> 501 raise ConnectionError(err, request=request) 503 except MaxRetryError as e: 504 if isinstance(e.reason, ConnectTimeoutError): 505 # TODO: Remove this in 3.0.0: see #2811 ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))" }

At the moment, my guess is that the error is related to the failures of the algorithm, since I'm also getting if for a lower execution time when I increase the error rate of my backend.

positr0nium commented 6 months ago

Hi, what do you mean by increasing the error-rate? Are you using the noisy IBM simulator?

diehoq commented 6 months ago

I'm using the Alice&Bob Qiskit provider (https://github.com/Alice-Bob-SW/qiskit-alice-bob-provider). It is based on the IBM noisy simulator, where we apply the noise model for each gate.

positr0nium commented 6 months ago

A possible problem might be that the simulation runs out of memory and crashes the server (which results in a connection reset). Could you modify the following code such that it directly runs qiskit_qc on your backend and see if it crashes.

def get_r_candidates(approx):
    rationals = continued_fraction_convergents(continued_fraction_iterator(Rational(approx)))
    return [rat.q for rat in rationals]

def find_order(a, N): 
    qg = QuantumModulus(N)
    qg[:] = 1
    qpe_res = QuantumFloat(2*qg.size + 1, exponent = -(2*qg.size + 1))
    h(qpe_res)
    x=a
    for i in range(len(qpe_res)):
        with control(qpe_res[i]):
            qg *= x
            x = (x*x)%N
    QFT(qpe_res, inv = True)
    qiskit_qc = qpe_res.qs.compile().to_qiskit()
    # run qiskit_qc with your backend here and see if it crashes.
    return qpe_res.get_measurement(backend=vrtl_qasm_sim)

def quantum_shor(a,N):
    meas_res = find_order(a,N)
    r_candidates = sum([get_r_candidates(approx) for approx in meas_res.keys()], [])
    for cand in r_candidates:
        if (a**cand)%N == 1:
            r = cand
            break
    else:
        raise Exception("Please sample again")
    if r % 2:
        raise Exception("Please choose another a")
    p = np.gcd(a**(r//2)+1, N)
    q = int(N/p)
    if(p>q):
        return(q,p)
    return(p,q)

for _ in range(10):
    print(quantum_shor(a,N))

In any case, we will need to adjust the error message, so thank you for your report :)