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

SpikeGLXRawIO event extraction from XD channels is memory inefficient #1610

Open
h-mayorquin opened this issue Dec 11, 2024 · 1 comment
Open
Milestone

Comments

@h-mayorquin
Copy link
Contributor

h-mayorquin commented Dec 11, 2024

I am reading a nidq file of about 3 hours with reported size of 2.8 GiB. Reading with the following:

from pathlib import Path 


folder_path = Path("/home/heberto/data/just_nidq")


from neo.rawio.spikeglxrawio import SpikeGLXRawIO


rawio = SpikeGLXRawIO(dirname=folder_path)
rawio.parse_header()

Leads to an RSS allocation of 3.8 GiB.

Command line: /home/heberto/miniconda3/envs/work/bin/memray run --native --follow-fork dev.py
Start time: 2024-12-11 13:47:45.762000-06:00
End time: 2024-12-11 13:47:47.532000-06:00
Duration: 0:00:01.770000
Total number of allocations: 42613
Total number of frames seen: 3262
Peak memory usage: 3.9 GiB
Python allocator: pymalloc

The problem could be solved by delaying this parsing to _get_event_timestamps

# No events
event_channels = []
# This is true only in case of 'nidq' stream
for stream_name in stream_names:
if "nidq" in stream_name:
info = self.signals_info_dict[0, stream_name]
if len(info["digital_channels"]) > 0:
# add event channels
for local_chan in info["digital_channels"]:
chan_name = local_chan
chan_id = f"{stream_name}#{chan_name}"
event_channels.append((chan_name, chan_id, "event"))
# add events_memmap
data = np.memmap(info["bin_file"], dtype="int16", mode="r", offset=0, order="C")
data = data.reshape(-1, info["num_chan"])
# The digital word is usually the last channel, after all the individual analog channels
extracted_word = data[:, len(info["analog_channels"])]
self._events_memmap = np.unpackbits(extracted_word.astype(np.uint8)[:, None], axis=1)
event_channels = np.array(event_channels, dtype=_event_channel_dtype)

@zm711 zm711 added this to the 0.14.0 milestone Dec 13, 2024
@samuelgarcia
Copy link
Contributor

Reading events while parsing header is a big mess in neo.rawio.
We should have option to not parse events for all reader to avoid this.
Very often it needs a big memmap and also sometimes a np.nonzero() which is terrible.

@alejoe91 alejoe91 modified the milestones: 0.14.0, 0.15.0 Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants