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

“Lazy Map” capability for the BQSKit runtime #260

Open
WolfLink opened this issue Jul 17, 2024 · 3 comments
Open

“Lazy Map” capability for the BQSKit runtime #260

WolfLink opened this issue Jul 17, 2024 · 3 comments
Labels
feature request New feature or request

Comments

@WolfLink
Copy link
Collaborator

WolfLink commented Jul 17, 2024

I’d like the ability to perform a “lazy map”, meaning to have a RuntimeFuture to which I can submit more tasks. Here’s an example scenario where this would be useful:

  1. I start an asynchronous task A
  2. I perform some other code
  3. I start an asynchronous task B
  4. I wait for a result from either A or B (whichever finishes first)
  5. I cancel the other task (or all such other tasks if you expand this pattern beyond 2 tasks).

I imagine the code looking something like this:

lazy_map = get_runtime().lazy_map()
lazy_map.submit(A)
# other code
lazy_map.submit(B)
result = await lazy_map
lazy_map.cancel()

Another way to do this would be a way to await a list of futures

@WolfLink WolfLink added the feature request New feature or request label Jul 17, 2024
@edyounis
Copy link
Member

We do have the get_runtime().next(), but the functionality is tied to a map future.

Is what you are asking for here to be able to add additional slots to an existing in-flight task? That is, do you expect A to start running, or be ready to, as soon as you submit it?

If so, we could probably create a "submit_additional" or "map_additional" method that takes a future and a task and appends the task to the existing future while submitting it to the runtime rather than creating a new future. We would have to just be sure that the mailbox attached to the future is valid and alive.

@WolfLink
Copy link
Collaborator Author

WolfLink commented Jul 19, 2024

Yeah that's more or less the idea I am going for. For context, the specific code I have that inspired this idea is similar to:

A_future = get_runtime.map(...)
B_futures = []
async for result in FutureIterate(A_future):
    if condition(result):
        B_futures.append(get_runtime.submit(...))
    if other_condition(result):
        get_runtime().cancel(A_future)
        break

B_results = [await B_future for B_future in B_futures]

This works fine for now because I do want to look at all the results from B_futures, but I might at some point instead just want to get the "first good result" from B_futures. I would want some code like:

async for result in FutureIterate(B_futures):
    if condition(result):
        get_runtime().cancel(B_futures)
        return result
return None

This is currently not possible to implement with the existing BQSKit runtime features.

Tangentially, FutureIterate is a tool I wrote that wraps calls to get_runtime().next(map_future) in an async iterator such that it can be used in an async for loop. This might be a tool that would be good to have in BQSKit.

@WolfLink
Copy link
Collaborator Author

I have encountered a real-world use case where I would like this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants