AllenNeuralDynamics / exa-spim-control

Acquisition control for the exaSPIM microscope system
MIT License
2 stars 1 forks source link

Remove dangling image copy operation #17

Open Poofjunior opened 1 year ago

Poofjunior commented 1 year ago

The eGrabber api showcases an example where you can write to an existing buffer. Pasted below.

"""Grab into user allocated buffer. sample240.py"""

from egrabber import *

gentl = EGenTL()
grabber = EGrabber(gentl)
payload_size = grabber.get_payload_size()
user_buffer = bytearray(payload_size)
grabber.announce_and_queue(UserMemory(user_buffer))
grabber.start(1)
with Buffer(grabber) as buffer:
    base = buffer.get_info(BUFFER_INFO_BASE, INFO_DATATYPE_PTR)
    data_size = buffer.get_info(BUFFER_INFO_DATA_SIZE, INFO_DATATYPE_SIZET)
    print('User memory address: {}, buffer data size: {}'.format(base, data_size))
grabber.stop()
grabber.realloc_buffers(0)

It would be a huge win to be able to write this into the shared memory double buffer so that the image would never have to be copied.

Note: that this is only practical if we

  1. do not need to do any point-operations before sending the image to ImarisWriter. (i.e: transposing the image.)
  2. do not need to use a copy of the image anywhere else. (This could be tricky with MIPs, but still doable.)
Poofjunior commented 1 year ago

It looks like the way to write directly to shared memory would be to pass a subset of the shared memory buf attribute into the UserMemory object.

Something like this:

from mulitprocessing.shared_memory import SharedMemory
from egrabber import UserMemory

# Assume a 10 pixel image.
shm = SharedMemory(create=True, size=100)
img_mem = UserMemory(shm.buf[:10]) # first image
img_mem = UserMemory(shm.buf[10:20]) # later images offset deeper into memory.
Poofjunior commented 1 year ago

Another note: since we're writing images to buffers, we can remove the need to do any image copies if we simply send over the most recent image directly out of the buffer. We need to track the previous buffer index to have another thread access the right image for a live view. (We could probably do this in the Shared Double Buffer object.)