bloqade-python icon indicating copy to clipboard operation
bloqade-python copied to clipboard

Use case: Persistent back-end

Open jon-wurtz opened this issue 2 years ago • 5 comments

Continuing the saga of backend.submit(job) vs. job.backend.submit(). Initializing some persistent backend object to connect to a hardware accelerator means that you only need to do that once, eg

backend = BraketBackend()
backend.submit(job) # option A
job.submit(backend) # option B

In comparison, we create a new backend instance every time we submit a job https://github.com/QuEraComputing/bloqade-python/blob/da30a4279f38d92672730a42c0c036ea7771a665/src/bloqade/builder/emit.py#L583C12-L583C12!

All I am arguing for is to have this backend be persistent. For example, this way we could reserve resources for a particular task; communicate to a scheduler that we may need to do a task soon; have a persistent connection for triggering job responses; pre-authenticating credentials; and so forth. Breaking out the backend will allow for much more flexibility. There is a reason why everyone does this...

jon-wurtz avatar Aug 05 '23 14:08 jon-wurtz

option A or option B doesn't really matter for consistency I prefer option B, and I agree option B might make sense over strs I actually considered it. It has better linting support than str. But not because of persistent connection, which I don't think it's possible because we currently don't have any state send back from the server at backend construction time, see below

have a persistent connection for triggering job responses;

what is "persistent connection"? I don't see why you are/should be able to bypass the verification if you are not submitting jobs with special priority. The credentials are not backends, they are credentials towards a specific vendor, e.g quera can have 3 backends but only one credential is needed for one account. That is cached in a local file for a certain time, same in AWS case.

@weinbe58 I think it makes sense to query capabilities at the creation of backend object, I did that for IBM devices, I'm wondering if our capabilities query requires queries other than credentials? Or that is also something you only query once? Currently I don't see where we query that but I think that should be created when one creates a backend which now makes more sense to have an object.

Roger-luo avatar Aug 05 '23 15:08 Roger-luo

A persistent connection could, for example,

be a webhook to the server so that it immediately tells and triggers you when a measurement is done so that you could create a new one;

Reserve some hardware accelerator time so that no other jobs can run at the same time;

Have a persistent tunnel between resources;

Some SSO thing that you only need to authenticate once (imagine authenticating every time you submit a job yuck)-- for example consider python requests.Session(). I have some old code as an example if you really want to see what Jonathan was doing in his free time in 2017.

And bonus points, it gives an extremely natural way to memorize all jobs that have been sent to the hardware accelerator.

Hiding all of this from the user only hinders. Focusing only on today's application breaks tomorrow's.

jon-wurtz avatar Aug 06 '23 02:08 jon-wurtz

I'm wondering if our capabilities query requires queries other than credentials?

yes currently both for braket and our internal API you need credentials to access the capabilities.

I'm wondering if our capabilities query requires queries other than credentials? Or that is also something you only query once? Currently I don't see where we query that but I think that should be created when one creates a backend which now makes more sense to have an object.

you only need to do this once, I currently query the capabilities before compiling the to the quera schema. we could in principle do this every time you create the backend as well.

weinbe58 avatar Aug 06 '23 03:08 weinbe58

A persistent connection could, for example,

be a webhook to the server so that it immediately tells and triggers you when a measurement is done so that you could create a new one;

Reserve some hardware accelerator time so that no other jobs can run at the same time;

Have a persistent tunnel between resources;

Yes this definitely is a use-case, however, I can definitely think of how to incorporate this concept into our current interface without having the user create a persistent object explicitly.

Hiding all of this from the user only hinders. Focusing only on today's application breaks tomorrow's.

I don't think this is fair, nothing we have done precludes what creating structures like this.

weinbe58 avatar Aug 06 '23 03:08 weinbe58

How to integrate a persistent resource into our current design is very simple. There are two different modes of operation one typically works with, the first is running a batch job which consistent of a set of tasks that a user would like to submit and analyze later, the second is a "interactive" job where the user wants to get feedback from the QPU in real time and update submissions based on that feedback.

In our API we have these two modes already, the first goes like

Batch

future = builder.assign(...).batch_assign(...).backend(...).submit(...)
results = future.report().bitstrings

Interactive

while the latter involes flatten, an API that generates a callable object

callable = builder.assign(...).flatten(list_of_args).backend(...)
call_1 = callable(..., shots=10)
call_2 = callable(..., shots=10)

We would rename flatten to interactive if that is preferable, however, the user doesn't need to create a persistent object

I propose that the callable object would be able to open up a persistent connection that would make sure to save the resouces for every successive call.

Now the one use-case this won't actually work for is sharing the persistent connection across multiple simultaneous programs. I'm not sure if that is such a big deal anyways though.

weinbe58 avatar Aug 06 '23 03:08 weinbe58