# Out of order overlap
for i, tensor in enumerate(tensors):
def compute_then_offload():
tensor.mul_(2.0)
offloader.async_write(tensor)
offloader.async_read(tensor, callback=compute_then_offload)
offloader.synchronize()
Changes behind the scene
The change is simple but powerful: we add a wait() in each async_read/write call.
For those who want async_* without invoking callback, we provide _async_*_nowait method for more control.
import torch
from tensornvme import DiskOffloader
offloader = DiskOffloader('./offload')
tensors = []
for _ in range(10):
tensor = torch.rand(2, 2)
tensors.append(tensor)
print(tensor)
offloader.sync_write(tensor)
print("== computing! ==")
# Out of order overlap
for i, tensor in enumerate(tensors):
def compute_then_offload():
tensor.mul_(2.0)
offloader.async_write(tensor)
offloader.async_read(tensor, callback=compute_then_offload)
offloader.synchronize()
for tensor in tensors:
offloader.sync_read(tensor)
print(tensor)
What's new
We can write callback more elegantly, like this:
Changes behind the scene
The change is simple but powerful: we add a
wait()
in eachasync_read/write
call.async_*
without invoking callback, we provide_async_*_nowait
method for more control.To visualize what will happen:
Background
In async data structures, it's a common practice to notify other threads while accessing methods.
Take python's
queue.Queue
as example:Example and Test
Manual test script:
Expected output: