Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent double authentication while using openqaoa-azure #233

Closed
2 tasks done
vishal-ph opened this issue May 17, 2023 · 8 comments
Closed
2 tasks done

Prevent double authentication while using openqaoa-azure #233

vishal-ph opened this issue May 17, 2023 · 8 comments
Assignees
Labels
bug Something isn't working

Comments

@vishal-ph
Copy link
Collaborator

Prerequisites

Before raising this issue, I have already checked that I am:

  • running the latest version
  • made sure that this issue has not already been filed

Describe the bug

Running a QAOA problem using the OpenQAOA workflow as described in this notebook will require web authentication twice before executing the run. For reference, see the attached screenshot.

This happens because DeviceAzure, which is defined in src/openqaoa-azure/openqaoa_azure/backends/devices.py, has a method called check_connection, that is called twice, once from within the workflow and the other time from within the backend object.

To Reproduce

Steps to reproduce the behavior:

  1. Create the Azure device object
  2. Create a qubo for a problem of choice
  3. Initialize the QAOA workflow as q = QAOA()
  4. Call the compile method and pass the QUBO via q.compile(qubo)

Expected behavior

Upon executing the above steps, the web authenticator should only prompt once for device authentication

Screenshots

image

@vishal-ph vishal-ph added bug Something isn't working unitary_fund A feature supported by an UF grant and removed unitary_fund A feature supported by an UF grant labels May 17, 2023
@WingCode
Copy link

@vishal-ph I would like to take a stab at this issue. Could you assign it to me?

@vishal-ph
Copy link
Collaborator Author

vishal-ph commented May 29, 2023

NOTE: - Please branch out from openqaoa/dev and will make the PR into openqaoa/dev. Thanks

@TerraVenil
Copy link
Contributor

Hi, @vishal-ph. I was trying to reproduce the issue with steps described above. My code is below

from openqaoa import QAOA
from openqaoa.backends import create_device

device_azure = create_device(location='azure',
                             name='ionq.simulator',
                             resource_id="/subscriptions/****/resourceGroups/****/providers/****/Workspaces/****",
                             az_location='westus')

q = QAOA()
q.set_device(device_azure)
q.set_backend_properties(n_shots=1000)
q.set_classical_optimizer(maxiter=5)

from openqaoa.problems import NumberPartition

np_integer = NumberPartition([1,2,3])
np_qubo = np_integer.qubo

q.compile(np_qubo)

and my results after the execution code above is the following:
image
I have only changed timeout from 300s to 3 to skip long waiting for authentication. As you can see internally the authenticator throws an exception after some period of time. May I ask you to provide code to be able to reproduce this issue locally?

The next thing regarding

This happens because DeviceAzure, which is defined in src/openqaoa-azure/openqaoa_azure/backends/devices.py, has a method called check_connection, that is called twice, once from within the workflow and the other time from within the backend object.

I found that method check_connectioncalled withing workflow here https://github.com/entropicalabs/openqaoa/blob/dev/src/openqaoa-core/openqaoa/algorithms/qaoa/qaoa_workflow.py#L218 and probably you meant this call https://github.com/entropicalabs/openqaoa/blob/dev/src/openqaoa-core/openqaoa/backends/basebackend.py#L563 inside QAOABaseBackendCloud but I can't find any reference to it in steps to reproduce.

So please give more details to have a more clear picture of what is going on.

@vishal-ph
Copy link
Collaborator Author

@TerraVenil, thanks for taking a look at this issue! Regarding your questions:

  • Judging from your screenshot, it seems your CLI is not set up with Azure credentials. To access the devices from Azure and use them with OpenQAOA, you must first set up Azure CLI. Instructions to do that can be found here. In case, the issue is something else, please let me know!
  • For the second part of your question, you can look here and notice that the check_connection method of the device object verifies if connections to both provider and QPU are made, and returns True if both self.provider_connected and self.qpu_connected are True, or if self.provider_connected is True and self.device_name == ""
    As you rightly pointed out, the check_connection is in the qaoa_workflow.py and basebackend.py. However, I think we can add conditionals, in the backend file that first check whether the device.provider_connected and device.qpu_connected are already True and skip check_connection if that's the case.

Let me know if you still have questions or something is unclear! Thanks

@TerraVenil
Copy link
Contributor

TerraVenil commented Jun 8, 2023

Judging from your screenshot, it seems your CLI is not set up with Azure credentials. To access the devices from Azure and use them with OpenQAOA, you must first set up Azure CLI. Instructions to do that can be found here. In case, the issue is something else, please let me know!

I have installed Azure CLI and also provided the correct resourceId and location. Screenshot demonstrated that Azure Quantum iterates over a list of credentials to find the most appropriate to current user setup. So now I intentionally skipped the step of az login to reproduce an issue when to authenticate a user an interactive browser session required in Azure that corresponds to InteractiveBrowserCredential or DeviceCodeCredential. And from the screenshot we can see that eventually if you don't specify any login information Azure Quantum will throw timeout exception that an seen for both InteractiveBrowserCredential and DeviceCodeCredential. Question how you were able to achieve two sequential requests from a web authenticator still open :)

For the second part of your question, you can look here and notice that the check_connection method of the device object verifies if connections to both provider and QPU are made, and returns True if both self.provider_connected and self.qpu_connected are True, or if self.provider_connected is True and self.device_name == ""
As you rightly pointed out, the check_connection is in the qaoa_workflow.py and basebackend.py. However, I think we can add conditionals, in the backend file that first check whether the device.provider_connected and device.qpu_connected are already True and skip check_connection if that's the case.

To understand if we necessarily need this check I have created small unit test to demonstrate such case

        shots = 100

        set_of_numbers = np.random.randint(1, 10, 6).tolist()
        qubo = NumberPartition(set_of_numbers).qubo

        mixer_hamil = X_mixer_hamiltonian(n_qubits=6)
        qaoa_descriptor = QAOADescriptor(qubo.hamiltonian, mixer_hamil, p=1)
        variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'rand')

        azure_device = DeviceAzure(
            device_name='ionq.simulator',
            resource_id="/subscriptions/****/resourceGroups/****/providers/****/Workspaces/****",
            az_location='westus'
        )

        azure_device.check_connection()

        # here in ctor we call check_connection() again
        qiskit_backend = QAOAQiskitQPUBackend(
            qaoa_descriptor, azure_device, shots, None, None, True
        )

        # in total we called check_connection twice
        circuit = qiskit_backend.qaoa_circuit(variate_params)
        job = qiskit_backend.backend_qpu.run(circuit, shots=qiskit_backend.n_shots)

Do we really expect that the user(is it a normal/obvious/intuitive scenario?) before using QAOAQiskitQPUBackend would call check_connection on DeviceAzure? Of course we should protect code from different scenarios but for example I could't find any similar workflow in existing unit tests base. Just to be sure that we are adding a useful feature. Thanks!

@TerraVenil
Copy link
Contributor

Ok, I found place where we want to avoid additional call to check_connection because obviously it was done before in scope of compile method and created PR.

@TerraVenil
Copy link
Contributor

@Q-lds or @vishal-ph please assign this issue to me. Thanks.

@Q-lds Q-lds assigned TerraVenil and unassigned WingCode Jun 13, 2023
@vishal-ph
Copy link
Collaborator Author

Fixed this issue in PR #249

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants