From 6740d9b36354b799dd3a8d29801628960b9043ab Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Wed, 9 Apr 2025 09:20:05 +0200 Subject: [PATCH] alignedData now uses std::align_alloc --- pyctbgui/pyctbgui/services/Signals.py | 46 +++++++++-------- slsReceiverSoftware/CMakeLists.txt | 1 + slsReceiverSoftware/include/sls/utils.h | 36 +++++++++++++ slsReceiverSoftware/src/DataProcessor.cpp | 62 ++++------------------- 4 files changed, 70 insertions(+), 75 deletions(-) create mode 100644 slsReceiverSoftware/include/sls/utils.h diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index 4f27ab886..856571e22 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -90,7 +90,7 @@ class SignalsTab(QtWidgets.QWidget): self.legend.addItem(plot, name) @recordOrApplyPedestal - def _processWaveformData(self, data, aSamples, dSamples, rx_reorder, rx_dbitlist, isPlottedArray, romode, + def _processWaveformData(self, data, aSamples, dSamples, rx_dbitreorder, rx_dbitlist, isPlottedArray, romode, nADCEnabled): #transform raw waveform data into a processed numpy array @@ -100,44 +100,46 @@ class SignalsTab(QtWidgets.QWidget): if romode == 2: start_digital_data += nADCEnabled * 2 * aSamples digital_array = np.array(np.frombuffer(data, offset=start_digital_data, dtype=np.uint8)) - if rx_reorder: - arr = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) + if rx_dbitreorder: + samples_per_bit = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) #stored per row all the corresponding signals of all samples nbitsPerDBit = dSamples if nbitsPerDBit % 8 != 0: nbitsPerDBit += (8 - (dSamples % 8)) - offset = 0 + bit_index = 0 for idx, i in enumerate(rx_dbitlist): # where numbits * numsamples is not a multiple of 8 - if offset % 8 != 0: - offset += (8 - (offset % 8)) + if bit_index % 8 != 0: + bit_index += (8 - (bit_index % 8)) if not isPlottedArray[i]: - offset += nbitsPerDBit - arr[idx, :] = np.nan + bit_index += nbitsPerDBit + samples_per_bit[idx, :] = np.nan continue for iSample in range(dSamples): # all samples for digital bit together from slsReceiver - index = int(offset / 8) - iBit = offset % 8 + index = int(bit_index / 8) + iBit = bit_index % 8 bit = (digital_array[index] >> iBit) & 1 - arr[idx,iSample] = bit - offset += 1 - return arr + samples_per_bit[idx,iSample] = bit + bit_index += 1 + return samples_per_bit else: nbitsPerSample = len(rx_dbitlist) if len(rx_dbitlist) % 8 == 0 else len(rx_dbitlist) + (8 - (len(rx_dbitlist) % 8)) - arr = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store all samples + bits_per_sample = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store per row all selected bits of a sample for iSample in range(dSamples): - offset = nbitsPerSample * iSample + bit_index = nbitsPerSample * iSample for idx, i in enumerate(rx_dbitlist): if not isPlottedArray[i]: - offset += 1 - arr[iSample, idx] = np.nan + bit_index += 1 + bits_per_sample[iSample, idx] = np.nan - index = int(offset/8) + index = int(bit_index/8) iBit = idx % 8 bit = (digital_array[index] >> iBit) & 1 - arr[iSample, idx] = bit - offset += 1 - return arr.T.copy() + bits_per_sample[iSample, idx] = bit + bit_index += 1 + return bits_per_sample.T.copy() + + def processWaveformData(self, data, aSamples, dSamples): @@ -157,7 +159,7 @@ class SignalsTab(QtWidgets.QWidget): self.mainWindow.nADCEnabled) irow = 0 - for idx, i in enumerate(self.rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! + for idx, i in enumerate(self.rx_dbitlist): # bits enabled but not plotting waveform = digital_array[idx, :] if np.isnan(waveform[0]): diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index 543ff7467..9e6ad75c3 100755 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES set(PUBLICHEADERS include/sls/Receiver.h + include/sls/utils.h ) # HDF5 file writing diff --git a/slsReceiverSoftware/include/sls/utils.h b/slsReceiverSoftware/include/sls/utils.h new file mode 100644 index 000000000..3aa76456c --- /dev/null +++ b/slsReceiverSoftware/include/sls/utils.h @@ -0,0 +1,36 @@ +/** + * @file utils.cpp + * @short utility objects for Receiver + */ + +#include +#include + +namespace sls { + +/* + * AlignedData + * Aligns data to a given type T with proper alignment + * @param data: pointer to data + * @param size: size of data to align in bytes + */ +template struct AlignedData { + T *aligned_ptr; // aligned data pointer + + AlignedData(char *data, size_t size) { + if (reinterpret_cast(data) % alignof(uint64_t) == 0) { + // If aligned directly cast to pointer + aligned_ptr = reinterpret_cast(data); + + } else { + + auto alignedbuffer = std::aligned_alloc(alignof(T), size); + std::memcpy(alignedbuffer, data, size); + aligned_ptr = reinterpret_cast(alignedbuffer); + } + } + + ~AlignedData() { std::free(aligned_ptr); } +}; + +} // namespace sls \ No newline at end of file diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index b96f5042a..6a16284dd 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -24,51 +24,10 @@ #include #include +#include "sls/utils.h" + namespace sls { -// TODO: move somewhere else -template struct AlignedData { - T *ptr; // Aligned data pointer - std::unique_ptr[]> buffer; - - AlignedData( - T *p, - std::unique_ptr[]> buf) - : ptr(p), buffer(std::move(buf)) {} -}; - -// TODO: should not be in this file any suggestions to move it to a more -// appropriate file? -// TODO: Add unit test -/* - * AlignData - * Aligns data to a given type T with proper alignment - * @param data: pointer to data - * @param size: size of data to align in bytes - * @return: aligned data - */ -template -void AlignData(AlignedData &aligneddata, char *data, size_t size) { - using AlignedBuffer = - typename std::aligned_storage::type; - std::unique_ptr tempbuffer; - - if (reinterpret_cast(data) % alignof(uint64_t) == 0) { - // If aligned directly cast to pointer - - aligneddata.ptr = reinterpret_cast(data); - - } else { - // Allocate a temporary buffer with proper alignment - tempbuffer = std::make_unique(size / sizeof(T)); - // size = ctbDigitaldbt; - - std::memcpy(tempbuffer.get(), data, size); - aligneddata.buffer = std::move(tempbuffer); - aligneddata.ptr = reinterpret_cast(aligneddata.buffer.get()); - } -} - const std::string DataProcessor::typeName = "DataProcessor"; DataProcessor::DataProcessor(int index) : ThreadObject(index, typeName) { @@ -617,11 +576,10 @@ void DataProcessor::Reorder(size_t &size, char *data) { } // make sure data is aligned to 8 bytes before casting to uint64_t - AlignedData aligned_data(nullptr, nullptr); - AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); + AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); - uint64_t *source = aligned_data.ptr; + uint64_t *source = aligned_data.aligned_ptr; const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -694,13 +652,11 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { return; } - AlignedData aligned_data(nullptr, nullptr); - AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); + // make sure data is aligned to 8 bytes before casting to uint64_t + AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); - uint64_t *source = aligned_data.ptr; - - // auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + uint64_t *source = aligned_data.aligned_ptr; const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t));