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

[BBPBGLIB-712] Estimate memory usage for synapse and connection #22

Merged
merged 6 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
64 changes: 64 additions & 0 deletions _benchmarks/synstats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Small script to measure memory usage of synapse objects in NEURON.
# Usage: nrniv (or special) -python synstats.py

from neuron import h
import os


def get_mem_usage():
"""
Return memory usage information in MB.
"""
with open("/proc/self/statm") as fd:
_, data_size, _ = fd.read().split(maxsplit=2)
usage_mb = float(data_size) * os.sysconf("SC_PAGE_SIZE") / 1024 ** 2

return usage_mb


# Dummy class to pass to synapse objects
class SynParams:
def __getattr__(self, item):
return 1


n_inst = 1000000

h.load_file("RNGSettings.hoc")
h.load_file("Map.hoc")

map_hoc = h.Map()
RNGset = h.RNGSettings()
RNGset.interpret(map_hoc)

pc = h.ParallelContext()

sec = h.Section()
sec.push()
params_obj = SynParams()

h.load_file("AMPANMDAHelper.hoc")
mem = get_mem_usage()
AMPA_helper = [h.AMPANMDAHelper(1, params_obj, 0.5, i, 0) for i in range(n_inst)]
netcon_ampa = [pc.gid_connect(1000, helper.synapse) for helper in AMPA_helper]
mem2 = get_mem_usage()
print('Memory usage per object ProbAMPA: %f KB' % ((mem2 - mem) / n_inst * 1024))

h.load_file("GABAABHelper.hoc")
mem = get_mem_usage()
GABAAB_helper = [h.GABAABHelper(1, params_obj, 0.5, i, 0) for i in range(n_inst)]
netcon_gabaab = [pc.gid_connect(1000, helper.synapse) for helper in GABAAB_helper]
mem2 = get_mem_usage()
print('Memory usage per object ProbGABAAB: %f KB' % ((mem2 - mem) / n_inst * 1024))

h.load_file("GluSynapseHelper.hoc")
mem = get_mem_usage()
GluSynapse_helper = [h.GluSynapseHelper(1, params_obj, 0.5, i, 0, map_hoc) for i in range(n_inst)]
netcon_glu = [pc.gid_connect(1000, helper.synapse) for helper in GluSynapse_helper]
mem2 = get_mem_usage()
print('Memory usage per object GluSynapse: %f KB' % ((mem2 - mem) / n_inst * 1024))

mem = get_mem_usage()
Gap_helper = [h.Gap(0.5) for i in range(n_inst)]
mem2 = get_mem_usage()
print('Memory usage per object Gap: %f KB' % ((mem2 - mem) / n_inst * 1024))
18 changes: 15 additions & 3 deletions neurodamus/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .utils import compat
from .utils.logging import log_stage, log_verbose, log_all
from .utils.memory import trim_memory, pool_shrink, free_event_queues, print_mem_usage
from .utils.memory import SynapseMemoryUsage
from .utils.timeit import TimerManager, timeit
# Internal Plugins
from . import ngv as _ngv # NOQA
Expand Down Expand Up @@ -629,15 +630,26 @@ def _find_config_file(self, filepath, path_conf_entries=(), alt_filename=None):
def _collect_display_syn_counts(local_syn_counter):
xelist = [local_syn_counter] + [None] * (MPI.size - 1) # send to rank0
counters = MPI.py_alltoall(xelist)
inh = exc = 0
syn_mem = SynapseMemoryUsage()

if MPI.rank == 0:
log_stage("Synapse counts (per type)")
log_stage("Synapse memory estimate (per type)")
master_counter = Counter()
for c in counters:
master_counter.update(c)

for synpse_type, count in master_counter.items():
logging.info(f" - {synpse_type}: {count}")
for synapse_type, count in master_counter.items():
logging.debug(f" - {synapse_type}: {count}")
if synapse_type < 100:
inh += count
if synapse_type >= 100:
exc += count
logging.info(" - Estimated synapse memory usage (KB):")
in_mem = syn_mem.get_memory_usage(inh, "ProbGABAAB")
ex_mem = syn_mem.get_memory_usage(exc, "ProbAMPANMDA")
logging.info(f" - Inhibitory: {in_mem}")
logging.info(f" - Excitatory: {ex_mem}")

# -
@mpi_no_errors
Expand Down
24 changes: 24 additions & 0 deletions neurodamus/utils/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,27 @@ def get_mem_usage():
usage_mb = float(data_size) * os.sysconf("SC_PAGE_SIZE") / 1024 ** 2

return usage_mb


class SynapseMemoryUsage:
''' A small class that works as a lookup table
for the memory used by each type of synapse.
The values are in KB. The values cannot be set by the user.
'''
def __init__(self):
self._synapse_memory_usage = {
st4rl3ss marked this conversation as resolved.
Show resolved Hide resolved
"ProbAMPANMDA": 1.7,
"ProbGABAAB": 2.0,
"Gap": 2.0,
"Glue": 0.5
}

def __getitem__(self, item):
return self._synapse_memory_usage[item]

def __setitem__(self, key, value):
raise ValueError("Cannot set values in SynapseMemoryUsage. "
"Values are hardcoded.")
st4rl3ss marked this conversation as resolved.
Show resolved Hide resolved

def get_memory_usage(self, count, synapse_type):
return count * self._synapse_memory_usage[synapse_type]