-
Notifications
You must be signed in to change notification settings - Fork 68
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
Asynchronous API improvements #216
Comments
Complication: Adding is not always the correct merging method. In particular if we support MapReduce, this will have to be the reducer function. In that case we have to actually call the thile's method and live with the fact that we might have to manage result buffer and image buffer separately. with api.AsyncContext.create() as ctx:
ds = ctx.load(...)
analysis = ctx.create_mask_analysis(dataset=ds, factories=[mask0, mask1])
# TODO how to handle the result shape best for Analysis vs. Job?
result_shape = analysis.get_result_shape()
image1 = create_image(np.zeros(tuple(result_shape.sig)))
image2 = create_image(np.zeros(tuple(result_shape.sig)))
image1.Show()
image2.Show()
async for part_result in ctx.run(job):
# TODO can the individual result tiles perhaps be pre-assembled so that
# the for loop is not necessary?
# Difficulty: The calculation results can arrive
# completely out of order
for tile in part_result.mask_0:
tile.reduce_into_result(image1.buf)
for tile in part_result.mask_1:
tile.reduce_into_result(image2.buf)
image1.Refresh()
image2.Refresh() |
I think so, yes. My first approach would be to make async the default, and wrap it for the sync case (wrapping could be done with something like The approach of dask.distributed appears to be to run async code in a new loop, in a different thread. Concerning the interface, I thought about making So, I propose: For handling generators, something like this can be used (need to run in a separate thread though, to allow nesting): import asyncio
def async_to_sync_generator(gen):
"""
convert async generator `gen` to sync generator
"""
loop = asyncio.get_event_loop()
try:
while True:
yield loop.run_until_complete(gen.__anext__())
except StopAsyncIteration as e:
raise StopIteration() from e
async def async_generator():
"""
example async generator
"""
for i in range(9):
yield i
# usage in sync code:
g = async_generator()
for i in async_to_sync_generator(g):
print(i) Some more remarks:
This should already be the case. For each mask, an I think the buffer allocation remarks should be solved together with UDF support. I'm actually leaning towards using the UDF interface also for internal functions (and implementing a
See above: the UDF interface should be quite a good match, we just need to make sure the outside interfaces (async and sync) are well-behaved and don't need to know about reduction functions etc. anymore. |
Sibling of #675 |
Interfaces for asynchronous |
Currently, using LiberTEM asynchronously requires importing code from deep within LiberTEM. Furthermore the interface can be made easier to use. Here are some notes and ideas from developing the Digital Micrograph asynchronous prototype:
The run() method could perhaps be used in the following way:
The text was updated successfully, but these errors were encountered: