From 6f2a6dd594a6c7501cbc38bbf20415e3a44b2f9c Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 9 Feb 2024 09:44:54 +0100 Subject: [PATCH 1/4] Version with memory leakage --- extern/limedriver | 2 +- src/limedriver/limedriver.pyx | 132 +++++++++++++++++----------------- 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/extern/limedriver b/extern/limedriver index f9d86bd..1eacc19 160000 --- a/extern/limedriver +++ b/extern/limedriver @@ -1 +1 @@ -Subproject commit f9d86bd4dea17250d9b0267936fb99d35a4ad1fd +Subproject commit 1eacc19c719445ddcceb276d9187e30f9f5c36d6 diff --git a/src/limedriver/limedriver.pyx b/src/limedriver/limedriver.pyx index f2d8728..144727f 100644 --- a/src/limedriver/limedriver.pyx +++ b/src/limedriver/limedriver.pyx @@ -95,7 +95,7 @@ cdef class PyLimeConfig: cdef LimeConfig_t* _config def __cinit__(self, Npulses): - self._config = malloc(sizeof(LimeConfig_t)) + self._config = PyMem_Malloc(sizeof(LimeConfig_t)) if self._config is NULL: raise MemoryError() @@ -103,79 +103,77 @@ cdef class PyLimeConfig: self._config.Npulses = Npulses # Allocate memory for string fields - self._config.file_pattern = malloc(256) - self._config.file_stamp = malloc(256) - self._config.save_path = malloc(256) - self._config.stamp_start = malloc(256) - self._config.stamp_end = malloc(256) + self._config.file_pattern = PyMem_Malloc(256) + self._config.file_stamp = PyMem_Malloc(256) + self._config.save_path = PyMem_Malloc(256) + self._config.stamp_start = PyMem_Malloc(256) + self._config.stamp_end = PyMem_Malloc(256) # Allocate memory for arrays with Npulses elements - self._config.p_dur = malloc(Npulses * sizeof(double)) - self._config.p_dur_smp = malloc(Npulses * sizeof(int)) - self._config.p_offs = malloc(Npulses * sizeof(int)) - self._config.p_amp = malloc(Npulses * sizeof(double)) - self._config.p_frq = malloc(Npulses * sizeof(double)) - self._config.p_frq_smp = malloc(Npulses * sizeof(double)) - self._config.p_pha = malloc(Npulses * sizeof(double)) - self._config.p_phacyc_N = malloc(Npulses * sizeof(int)) - self._config.p_phacyc_lev = malloc(Npulses * sizeof(int)) + self._config.p_dur = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_dur_smp = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_offs = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_amp = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_frq = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_pha = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_phacyc_N = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_phacyc_lev = PyMem_Malloc(Npulses * sizeof(int)) - self._config.am_frq = malloc(Npulses * sizeof(double)) - self._config.am_pha = malloc(Npulses * sizeof(double)) - self._config.am_depth = malloc(Npulses * sizeof(double)) - self._config.am_mode = malloc(Npulses * sizeof(int)) - self._config.am_frq_smp = malloc(Npulses * sizeof(double)) - self._config.fm_frq = malloc(Npulses * sizeof(double)) - self._config.fm_pha = malloc(Npulses * sizeof(double)) - self._config.fm_width = malloc(Npulses * sizeof(double)) - self._config.fm_mode = malloc(Npulses * sizeof(int)) - self._config.fm_frq_smp = malloc(Npulses * sizeof(double)) - self._config.p_c0_en = malloc(Npulses * sizeof(int)) - self._config.p_c1_en = malloc(Npulses * sizeof(int)) - self._config.p_c2_en = malloc(Npulses * sizeof(int)) - self._config.p_c3_en = malloc(Npulses * sizeof(int)) - - # Memory for arrays with 4 elements - self._config.RX_gain_rback = malloc(4 * sizeof(int)) - self._config.TX_gain_rback = malloc(3 * sizeof(int)) - self._config.c0_tim = malloc(4 * sizeof(int)) - self._config.c1_tim = malloc(4 * sizeof(int)) - self._config.c2_tim = malloc(4 * sizeof(int)) - self._config.c3_tim = malloc(4 * sizeof(int)) - - # Memory for arrays with 5 elements - self._config.c0_synth = malloc(5 * sizeof(int)) - self._config.c1_synth = malloc(5 * sizeof(int)) - self._config.c2_synth = malloc(5 * sizeof(int)) - self._config.c3_synth = malloc(5 * sizeof(int)) + self._config.am_frq = PyMem_Malloc(Npulses * sizeof(double)) + self._config.am_pha = PyMem_Malloc(Npulses * sizeof(double)) + self._config.am_depth = PyMem_Malloc(Npulses * sizeof(double)) + self._config.am_mode = PyMem_Malloc(Npulses * sizeof(int)) + self._config.am_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) + self._config.fm_frq = PyMem_Malloc(Npulses * sizeof(double)) + self._config.fm_pha = PyMem_Malloc(Npulses * sizeof(double)) + self._config.fm_width = PyMem_Malloc(Npulses * sizeof(double)) + self._config.fm_mode = PyMem_Malloc(Npulses * sizeof(int)) + self._config.fm_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) + self._config.p_c0_en = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_c1_en = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_c2_en = PyMem_Malloc(Npulses * sizeof(int)) + self._config.p_c3_en = PyMem_Malloc(Npulses * sizeof(int)) def __dealloc__(self): if self._config is not NULL: - free(self._config.p_frq) - free(self._config.p_dur) - free(self._config.p_dur_smp) - free(self._config.p_offs) - free(self._config.p_amp) - free(self._config.p_frq_smp) - free(self._config.p_pha) - free(self._config.p_phacyc_N) - free(self._config.p_phacyc_lev) - free(self._config.am_frq) - free(self._config.am_pha) - free(self._config.am_depth) - free(self._config.am_mode) - free(self._config.am_frq_smp) - free(self._config.fm_frq) - free(self._config.fm_pha) - free(self._config.fm_width) - free(self._config.fm_mode) - free(self._config.fm_frq_smp) - free(self._config.p_c0_en) - free(self._config.p_c1_en) - free(self._config.p_c2_en) - free(self._config.p_c3_en) + # Memory for arrays with Npulses elements + PyMem_Free(self._config.p_frq) + PyMem_Free(self._config.p_dur_smp) + PyMem_Free(self._config.p_offs) + PyMem_Free(self._config.p_amp) + PyMem_Free(self._config.p_frq_smp) + PyMem_Free(self._config.p_pha) + PyMem_Free(self._config.p_phacyc_N) + PyMem_Free(self._config.p_phacyc_lev) - free(self._config) + PyMem_Free(self._config.am_frq) + PyMem_Free(self._config.am_pha) + PyMem_Free(self._config.am_depth) + PyMem_Free(self._config.am_mode) + PyMem_Free(self._config.am_frq_smp) + PyMem_Free(self._config.fm_frq) + PyMem_Free(self._config.fm_pha) + PyMem_Free(self._config.fm_width) + PyMem_Free(self._config.fm_mode) + PyMem_Free(self._config.fm_frq_smp) + + PyMem_Free(self._config.p_c0_en) + PyMem_Free(self._config.p_c1_en) + PyMem_Free(self._config.p_c2_en) + PyMem_Free(self._config.p_c3_en) + + print("Freeing string fields") + # Memory for string fields + PyMem_Free(&self._config.file_pattern) + PyMem_Free(&self._config.file_stamp) + PyMem_Free(&self._config.save_path) + PyMem_Free(&self._config.stamp_start) + PyMem_Free(&self._config.stamp_end) + + print("Freeing LimeConfig_t") + # Free the main structure + PyMem_Free(self._config) @property From 4ee709a7ce64f3861e569a791b12f724c2f280e1 Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 9 Feb 2024 11:02:28 +0100 Subject: [PATCH 2/4] Fixed memory leakage. Thanks Kumi (Howdy Pardner)! Co-authored-by: Kumi --- src/limedriver/limedriver.pyx | 87 ++--------------------------------- 1 file changed, 4 insertions(+), 83 deletions(-) diff --git a/src/limedriver/limedriver.pyx b/src/limedriver/limedriver.pyx index 144727f..d8d6e47 100644 --- a/src/limedriver/limedriver.pyx +++ b/src/limedriver/limedriver.pyx @@ -92,89 +92,10 @@ cdef extern from "limedriver.h": cdef class PyLimeConfig: - cdef LimeConfig_t* _config + cdef LimeConfig_t _config def __cinit__(self, Npulses): - self._config = PyMem_Malloc(sizeof(LimeConfig_t)) - if self._config is NULL: - raise MemoryError() - - # Set Npulses - self._config.Npulses = Npulses - - # Allocate memory for string fields - self._config.file_pattern = PyMem_Malloc(256) - self._config.file_stamp = PyMem_Malloc(256) - self._config.save_path = PyMem_Malloc(256) - self._config.stamp_start = PyMem_Malloc(256) - self._config.stamp_end = PyMem_Malloc(256) - - # Allocate memory for arrays with Npulses elements - self._config.p_dur = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_dur_smp = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_offs = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_amp = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_frq = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_pha = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_phacyc_N = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_phacyc_lev = PyMem_Malloc(Npulses * sizeof(int)) - - self._config.am_frq = PyMem_Malloc(Npulses * sizeof(double)) - self._config.am_pha = PyMem_Malloc(Npulses * sizeof(double)) - self._config.am_depth = PyMem_Malloc(Npulses * sizeof(double)) - self._config.am_mode = PyMem_Malloc(Npulses * sizeof(int)) - self._config.am_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) - self._config.fm_frq = PyMem_Malloc(Npulses * sizeof(double)) - self._config.fm_pha = PyMem_Malloc(Npulses * sizeof(double)) - self._config.fm_width = PyMem_Malloc(Npulses * sizeof(double)) - self._config.fm_mode = PyMem_Malloc(Npulses * sizeof(int)) - self._config.fm_frq_smp = PyMem_Malloc(Npulses * sizeof(double)) - self._config.p_c0_en = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_c1_en = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_c2_en = PyMem_Malloc(Npulses * sizeof(int)) - self._config.p_c3_en = PyMem_Malloc(Npulses * sizeof(int)) - - def __dealloc__(self): - if self._config is not NULL: - # Memory for arrays with Npulses elements - PyMem_Free(self._config.p_frq) - PyMem_Free(self._config.p_dur_smp) - PyMem_Free(self._config.p_offs) - PyMem_Free(self._config.p_amp) - PyMem_Free(self._config.p_frq_smp) - PyMem_Free(self._config.p_pha) - PyMem_Free(self._config.p_phacyc_N) - PyMem_Free(self._config.p_phacyc_lev) - - PyMem_Free(self._config.am_frq) - PyMem_Free(self._config.am_pha) - PyMem_Free(self._config.am_depth) - PyMem_Free(self._config.am_mode) - PyMem_Free(self._config.am_frq_smp) - PyMem_Free(self._config.fm_frq) - PyMem_Free(self._config.fm_pha) - PyMem_Free(self._config.fm_width) - PyMem_Free(self._config.fm_mode) - PyMem_Free(self._config.fm_frq_smp) - - PyMem_Free(self._config.p_c0_en) - PyMem_Free(self._config.p_c1_en) - PyMem_Free(self._config.p_c2_en) - PyMem_Free(self._config.p_c3_en) - - print("Freeing string fields") - # Memory for string fields - PyMem_Free(&self._config.file_pattern) - PyMem_Free(&self._config.file_stamp) - PyMem_Free(&self._config.save_path) - PyMem_Free(&self._config.stamp_start) - PyMem_Free(&self._config.stamp_end) - - print("Freeing LimeConfig_t") - # Free the main structure - PyMem_Free(self._config) - + self._config = initializeLimeConfig(Npulses) @property def srate(self): @@ -826,9 +747,9 @@ cdef class PyLimeConfig: return instance def run(self): - return run_experiment_from_LimeCfg(self._config[0]) + return run_experiment_from_LimeCfg(self._config) def get_path(self): path = self.save_path + self.file_stamp + '_' + self.file_pattern + '.h5' path = pathlib.Path(path).absolute() - return path \ No newline at end of file + return path From 0b37e4b861b4154a0f880deb6affaf467c2f2f2c Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 9 Feb 2024 11:05:35 +0100 Subject: [PATCH 3/4] Removed init method since this is done by the c++ method. --- src/limedriver/limedriver.pyx | 78 +---------------------------------- 1 file changed, 1 insertion(+), 77 deletions(-) diff --git a/src/limedriver/limedriver.pyx b/src/limedriver/limedriver.pyx index d8d6e47..0fdb5a2 100644 --- a/src/limedriver/limedriver.pyx +++ b/src/limedriver/limedriver.pyx @@ -669,83 +669,6 @@ cdef class PyLimeConfig: def stamp_end(self, value): self._config.stamp_end = value.encode('utf-8') - @classmethod - def initialize(cls, int Npulses): - cdef LimeConfig_t config = initializeLimeConfig(Npulses) - - cdef PyLimeConfig instance = cls.__new__(cls, Npulses) - - instance.srate = config.srate - instance.frq = config.frq - instance.frq_set = config.frq_set - instance.RX_LPF = config.RX_LPF - instance.TX_LPF = config.TX_LPF - instance.RX_gain = config.RX_gain - instance.TX_gain = config.TX_gain - instance.TX_IcorrDC = config.TX_IcorrDC - instance.TX_QcorrDC = config.TX_QcorrDC - instance.TX_IcorrGain = config.TX_IcorrGain - instance.TX_QcorrGain = config.TX_QcorrGain - instance.TX_IQcorrPhase = config.TX_IQcorrPhase - instance.RX_IcorrGain = config.RX_IcorrGain - instance.RX_QcorrGain = config.RX_QcorrGain - instance.RX_IQcorrPhase = config.RX_IQcorrPhase - instance.RX_gain_rback = config.RX_gain_rback - instance.TX_gain_rback = config.TX_gain_rback - instance.Npulses = config.Npulses - instance.averages = config.averages - instance.repetitions = config.repetitions - instance.pcyc_bef_avg = config.pcyc_bef_avg - instance.reptime_secs = config.reptime_secs - instance.rectime_secs = config.rectime_secs - instance.reptime_smps = config.reptime_smps - instance.rectime_smps = config.rectime_smps - instance.buffersize = config.buffersize - instance.override_init = config.override_init - instance.override_save = config.override_save - - instance.file_pattern = config.file_pattern.decode('utf-8') - instance.file_stamp = config.file_stamp.decode('utf-8') - instance.save_path = config.save_path.decode('utf-8') - instance.stamp_start = config.stamp_start.decode('utf-8') - instance.stamp_end = config.stamp_end.decode('utf-8') - - - instance.p_dur = [config.p_dur[i] for i in range(Npulses)] - instance.p_dur_smp = [config.p_dur_smp[i] for i in range(Npulses)] - instance.p_offs = [config.p_offs[i] for i in range(Npulses)] - instance.p_amp = [config.p_amp[i] for i in range(Npulses)] - instance.p_frq = [config.p_frq[i] for i in range(Npulses)] - instance.p_frq_smp = [config.p_frq_smp[i] for i in range(Npulses)] - instance.p_pha = [config.p_pha[i] for i in range(Npulses)] - instance.p_phacyc_N = [config.p_phacyc_N[i] for i in range(Npulses)] - instance.p_phacyc_lev = [config.p_phacyc_lev[i] for i in range(Npulses)] - instance.am_frq = [config.am_frq[i] for i in range(Npulses)] - instance.am_pha = [config.am_pha[i] for i in range(Npulses)] - instance.am_depth = [config.am_depth[i] for i in range(Npulses)] - instance.am_mode = [config.am_mode[i] for i in range(Npulses)] - instance.am_frq_smp = [config.am_frq_smp[i] for i in range(Npulses)] - instance.fm_frq = [config.fm_frq[i] for i in range(Npulses)] - instance.fm_pha = [config.fm_pha[i] for i in range(Npulses)] - instance.fm_width = [config.fm_width[i] for i in range(Npulses)] - instance.fm_mode = [config.fm_mode[i] for i in range(Npulses)] - instance.fm_frq_smp = [config.fm_frq_smp[i] for i in range(Npulses)] - instance.p_c0_en = [config.p_c0_en[i] for i in range(Npulses)] - instance.p_c1_en = [config.p_c1_en[i] for i in range(Npulses)] - instance.p_c2_en = [config.p_c2_en[i] for i in range(Npulses)] - instance.p_c3_en = [config.p_c3_en[i] for i in range(Npulses)] - - instance.c0_tim = [config.c0_tim[i] for i in range(4)] - instance.c1_tim = [config.c1_tim[i] for i in range(4)] - instance.c2_tim = [config.c2_tim[i] for i in range(4)] - instance.c3_tim = [config.c3_tim[i] for i in range(4)] - instance.c0_synth = [config.c0_synth[i] for i in range(5)] - instance.c1_synth = [config.c1_synth[i] for i in range(5)] - instance.c2_synth = [config.c2_synth[i] for i in range(5)] - instance.c3_synth = [config.c3_synth[i] for i in range(5)] - - return instance - def run(self): return run_experiment_from_LimeCfg(self._config) @@ -753,3 +676,4 @@ cdef class PyLimeConfig: path = self.save_path + self.file_stamp + '_' + self.file_pattern + '.h5' path = pathlib.Path(path).absolute() return path + \ No newline at end of file From b00362aa16591612bffa46052af65416fe7f0235 Mon Sep 17 00:00:00 2001 From: jupfi Date: Fri, 9 Feb 2024 11:06:56 +0100 Subject: [PATCH 4/4] remobe debug prints. --- src/limedriver/hdf_reader.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/limedriver/hdf_reader.py b/src/limedriver/hdf_reader.py index bc1dc9d..7276717 100644 --- a/src/limedriver/hdf_reader.py +++ b/src/limedriver/hdf_reader.py @@ -34,7 +34,6 @@ class HDF(): else: f = h5py.File(self.HDFsrc, 'r') - print("opened file") HDFkeys = list(f.keys()) for ii, HDFkey in enumerate(HDFkeys): @@ -44,11 +43,9 @@ class HDF(): inddim = dsize[0] self.tdy = np.zeros((int(dsize[1]/2), int(dsize[0] * len(HDFkeys))),dtype=np.complex_) - print("initialize") # initialize the output objects self.attrs = [dynclass() for jj in range(len(HDFkeys))] - print("get the attribute keys") # get the attribute keys self.parsoutp = {} ii_oupargs = 0 @@ -62,9 +59,6 @@ class HDF(): self.parsoutp['//'+str(ii_oupargs)] = [ item[1], itemname] ii_oupargs+=1 - print("end of loop") - - print("look for vars") # look for eventual parvar lists self.parvar = {} for item in f.attrs.items():