Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 52 additions & 23 deletions neurodamus/connection_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,48 @@ def __del__(self):
if self.yielded_src_gids:
log_all(logging.DEBUG, "Source GIDs for debug cell: %s", self.yielded_src_gids)

@staticmethod
def _get_allowed_ranges(src_target, sgids, sgids_ranges, conn_count):
"""Return n_yielded_conns and allowed_ranges, handling src_target=None.

Helper function for _iterate_conn_params
"""
if src_target:
unique_sgids = sgids[sgids_ranges[:-1]]
allowed_sgids = set(unique_sgids[src_target.contains(unique_sgids, raw_gids=True)])
allowed_ranges = [
(sgids_ranges[i], sgids_ranges[i + 1])
for i in range(conn_count)
if sgids[sgids_ranges[i]] in allowed_sgids
]
n_yielded_conns = len(allowed_sgids)
else:
n_yielded_conns = conn_count
allowed_ranges = [(sgids_ranges[i], sgids_ranges[i + 1]) for i in range(conn_count)]

return n_yielded_conns, allowed_ranges

@staticmethod
def _compute_sgids_ranges(syns_params):
"""Compute source GIDs, their change points, and total connections count.

Helper function for _iterate_conn_params
"""
sgids = syns_params[syns_params.dtype.names[0]].astype("int64")
sgids_ranges = np.diff(sgids, prepend=np.nan, append=np.nan).nonzero()[0]
conn_count = len(sgids_ranges) - 1
return sgids, sgids_ranges, conn_count

def _get_extra_fields(self, base_tgid):
Comment thread
juanjosegarcan marked this conversation as resolved.
"""Get extra fields for the synapse parameters, e.g. synapse_index.

Helper function for _iterate_conn_params
"""
if self._load_offsets:
syn_index = self._synapse_reader.get_property(base_tgid, "synapse_index")
return {"synapse_index": syn_index}
return {}

def _iterate_conn_params( # noqa: PLR0914
self,
src_target,
Expand Down Expand Up @@ -587,14 +629,12 @@ def _iterate_conn_params( # noqa: PLR0914

self._synapse_reader.configure_override(mod_override)
self._synapse_reader.preload_data(gids, minimal_mode=SimConfig.cli_options.crash_test)
extra_fields = {} # Without extra fields, reuse this object

# NOTE: This routine is quite critical, sitting at the core of synapse processing
# so it has been carefully optimized with numpy vectorized operations, even if
# it might lose some readability.
# For each tgid we obtain the synapse parameters as a record array. We then split it,
# without copying, yielding ranges (views) of it.

if show_progress is None:
show_progress = len(gids) >= AUTO_PROGRESS_THRESHOLD

Expand All @@ -605,32 +645,21 @@ def _iterate_conn_params( # noqa: PLR0914
syns_params = self._synapse_reader.get_synapse_parameters(base_tgid)
logging.debug("GID %d Syn count: %d", tgid, len(syns_params))

if self._load_offsets:
syn_index = self._synapse_reader.get_property(base_tgid, "synapse_index")
extra_fields = {"synapse_index": syn_index}
sgids, sgids_ranges, conn_count = self._compute_sgids_ranges(syns_params)
conn_debugger = self.ConnDebugger()
if conn_count == 0:
logging.debug("No synapses for GID %d. Nothing to do.", tgid)
continue

extra_fields = self._get_extra_fields(base_tgid)

# We yield ranges of contiguous parameters belonging to the same connection,
# and given we have data for a single tgid, enough to group by sgid.
# The first row of a range is found by numpy.diff

sgids = syns_params[syns_params.dtype.names[0]].astype("int64") # src gid in field 0
sgids_ranges = np.diff(sgids, prepend=np.nan, append=np.nan).nonzero()[0]
conn_count = len(sgids_ranges) - 1
conn_debugger = self.ConnDebugger()

if src_target:
# create a set with the gids that belong both to the synapses and the target
unique_sgids = sgids[sgids_ranges[:-1]]
allowed_sgids = set(unique_sgids[src_target.contains(unique_sgids, raw_gids=True)])
n_yielded_conns = len(allowed_sgids)
allowed_ranges = [
(sgids_ranges[i], sgids_ranges[i + 1])
for i in range(conn_count)
if sgids[sgids_ranges[i]] in allowed_sgids
]
else:
n_yielded_conns = conn_count
allowed_ranges = [(sgids_ranges[i], sgids_ranges[i + 1]) for i in range(conn_count)]
n_yielded_conns, allowed_ranges = self._get_allowed_ranges(
src_target, sgids, sgids_ranges, conn_count
)

for range_start, range_end in allowed_ranges:
sgid = int(sgids[range_start])
Expand Down
2 changes: 1 addition & 1 deletion tests/simulations/ngv/create_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def make_ngv_nodes():
"z": it.count(2),
"morphology": "cell_small",
}
make_nodes(filename="nodes.h5", name="RingA", count=5, wanted_attributes=wanted)
make_nodes(filename="nodes.h5", name="RingA", count=7, wanted_attributes=wanted)

wanted = {
"node_type_id": -1,
Expand Down
Binary file modified tests/simulations/ngv/edges.h5
Binary file not shown.
Binary file modified tests/simulations/ngv/gliovascular.h5
Binary file not shown.
Binary file modified tests/simulations/ngv/neuroglia.h5
Binary file not shown.
Binary file modified tests/simulations/ngv/nodes.h5
Binary file not shown.
12 changes: 6 additions & 6 deletions tests/unit-ngv-mpi/test_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def test_distribution(create_tmp_simulation_config_file, mpi_ranks):
# Check allocation for RingA population
local_cells_gids = n.circuits.get_node_manager("RingA").local_nodes.final_gids()
if rank == 0:
local_cells_gids_ref = [1001, 1003, 1005]
local_cells_gids_ref = [1001, 1003, 1005, 1007]
elif rank == 1:
local_cells_gids_ref = [1002, 1004]
local_cells_gids_ref = [1002, 1004, 1006]
npt.assert_allclose(local_cells_gids, local_cells_gids_ref)

# Check allocation for Astrocites
Expand All @@ -42,11 +42,11 @@ def test_distribution(create_tmp_simulation_config_file, mpi_ranks):

# Check RingA cells spikes
if rank == 0:
spike_gid_ref = np.array([1001, 1003, 1005])
timestamps_ref = np.array([2.075, 2.075, 2.075])
spike_gid_ref = np.array([1001, 1003, 1005, 1007])
timestamps_ref = np.array([2.075]*len(spike_gid_ref))
elif rank == 1:
spike_gid_ref = np.array([1002, 1004])
timestamps_ref = np.array([2.075, 2.075])
spike_gid_ref = np.array([1002, 1004, 1006])
timestamps_ref = np.array([2.075]*len(spike_gid_ref))
ringA_spikes = n._spike_vecs[0]
timestamps = np.array(ringA_spikes[0])
spike_gids = np.array(ringA_spikes[1])
Expand Down
4 changes: 2 additions & 2 deletions tests/unit-ngv-mpi/test_radii_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ def test_vasccouplingB_radii(create_tmp_simulation_config_file, mpi_ranks):
n.run()

# Check RingA cells spikes
spike_gid_ref = np.array([1001, 1002, 1003, 1004, 1005])
timestamps_ref = np.array([2.075, 2.075, 2.075, 2.075, 2.075])
spike_gid_ref = np.array(range(1001, 1008))
timestamps_ref = np.array([2.075]*len(spike_gid_ref))
ringA_spikes = n._spike_vecs[0]
timestamps = np.array(ringA_spikes[0])
spike_gids = np.array(ringA_spikes[1])
Expand Down
Loading