alignedData now uses std::align_alloc

This commit is contained in:
Mazzoleni Alice Francesca 2025-04-09 09:20:05 +02:00
parent 1d1b55b864
commit 6740d9b363
4 changed files with 70 additions and 75 deletions

View File

@ -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]):

View File

@ -17,6 +17,7 @@ set(SOURCES
set(PUBLICHEADERS
include/sls/Receiver.h
include/sls/utils.h
)
# HDF5 file writing

View File

@ -0,0 +1,36 @@
/**
* @file utils.cpp
* @short utility objects for Receiver
*/
#include <cstdint>
#include <memory>
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 <typename T> struct AlignedData {
T *aligned_ptr; // aligned data pointer
AlignedData(char *data, size_t size) {
if (reinterpret_cast<uintptr_t>(data) % alignof(uint64_t) == 0) {
// If aligned directly cast to pointer
aligned_ptr = reinterpret_cast<T *>(data);
} else {
auto alignedbuffer = std::aligned_alloc(alignof(T), size);
std::memcpy(alignedbuffer, data, size);
aligned_ptr = reinterpret_cast<T *>(alignedbuffer);
}
}
~AlignedData() { std::free(aligned_ptr); }
};
} // namespace sls

View File

@ -24,51 +24,10 @@
#include <cstring>
#include <iostream>
#include "sls/utils.h"
namespace sls {
// TODO: move somewhere else
template <typename T> struct AlignedData {
T *ptr; // Aligned data pointer
std::unique_ptr<std::aligned_storage_t<sizeof(T), alignof(T)>[]> buffer;
AlignedData(
T *p,
std::unique_ptr<std::aligned_storage_t<sizeof(T), alignof(T)>[]> 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 <typename T>
void AlignData(AlignedData<T> &aligneddata, char *data, size_t size) {
using AlignedBuffer =
typename std::aligned_storage<sizeof(T), alignof(T)>::type;
std::unique_ptr<AlignedBuffer[]> tempbuffer;
if (reinterpret_cast<uintptr_t>(data) % alignof(uint64_t) == 0) {
// If aligned directly cast to pointer
aligneddata.ptr = reinterpret_cast<T *>(data);
} else {
// Allocate a temporary buffer with proper alignment
tempbuffer = std::make_unique<AlignedBuffer[]>(size / sizeof(T));
// size = ctbDigitaldbt;
std::memcpy(tempbuffer.get(), data, size);
aligneddata.buffer = std::move(tempbuffer);
aligneddata.ptr = reinterpret_cast<T *>(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<uint64_t> aligned_data(nullptr, nullptr);
AlignData<uint64_t>(aligned_data, data + nAnalogDataBytes + ctbDbitOffset,
AlignedData<uint64_t> 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<uint64_t> aligned_data(nullptr, nullptr);
AlignData<uint64_t>(aligned_data, data + nAnalogDataBytes + ctbDbitOffset,
// make sure data is aligned to 8 bytes before casting to uint64_t
AlignedData<uint64_t> 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));