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
74 changes: 36 additions & 38 deletions ALICE3/Core/FlatLutEntry.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

/// \file FlatLutEntry.cxx
/// \brief Flat LUT implementation for compact helper tables used by the ALICE3 track smearing workflow.

#include "FlatLutEntry.h"

#include <Framework/Logger.h>
Expand All @@ -22,33 +25,33 @@
#include <ios>
#include <span>

namespace o2::delphes
namespace o2::fastsim
{

void lutEntry_t::print() const
{
LOGF(info, " nch = %f, eta = %f, pt = %f, valid = %s\n", nch, eta, pt, valid ? "true" : "false");
LOGF(info, " eff = %f, eff2 = %f, itof = %f, otof = %f\n", eff, eff2, itof, otof);
LOGF(info, " covm: ");
for (int i = 0; i < 15; ++i) {
for (int i = 0; i < kNumCovarianceTerms; ++i) {
LOGF(info, "%f ", covm[i]);
}
LOGF(info, "\n");
LOGF(info, " eigval: ");
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < kNumEigenModes; ++i) {
LOGF(info, "%f ", eigval[i]);
}
LOGF(info, "\n");
LOGF(info, " eigvec:\n");
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
for (int i = 0; i < kNumEigenModes; ++i) {
for (int j = 0; j < kNumEigenModes; ++j) {
LOGF(info, "%f ", eigvec[i][j]);
}
LOGF(info, "\n");
}
LOGF(info, " eiginv:\n");
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
for (int i = 0; i < kNumEigenModes; ++i) {
for (int j = 0; j < kNumEigenModes; ++j) {
LOGF(info, "%f ", eiginv[i][j]);
}
LOGF(info, "\n");
Expand All @@ -57,23 +60,18 @@ void lutEntry_t::print() const

float map_t::fracPositionWithinBin(float val) const
{
float width = (max - min) / nbins;
int bin;
float returnVal = 0.5f;
const float width = (max - min) / nbins;
const int bin = find(val);
if (log) {
bin = static_cast<int>((std::log10(val) - min) / width);
returnVal = ((std::log10(val) - min) / width) - bin;
} else {
bin = static_cast<int>((val - min) / width);
returnVal = val / width - bin;
return ((std::log10(val) - min) / width) - bin;
}
return returnVal;
return val / width - bin;
}

int map_t::find(float val) const
{
float width = (max - min) / nbins;
int bin;
const float width = (max - min) / nbins;
int bin = 0;
if (log) {
bin = static_cast<int>((std::log10(val) - min) / width);
} else {
Expand All @@ -93,7 +91,7 @@ void map_t::print() const
LOGF(info, "nbins = %d, min = %f, max = %f, log = %s \n", nbins, min, max, log ? "on" : "off");
}

bool lutHeader_t::check_version() const
bool lutHeader_t::checkVersion() const
{
return (version == LUTCOVM_VERSION);
}
Expand All @@ -120,7 +118,7 @@ void FlatLutData::initialize(const lutHeader_t& header)
mEtaBins = header.etamap.nbins;
mPtBins = header.ptmap.nbins;

const size_t headerSize = sizeof(lutHeader_t);
constexpr size_t headerSize = sizeof(lutHeader_t);
const size_t numEntries = static_cast<size_t>(mNchBins) * mRadBins * mEtaBins * mPtBins;
const size_t entriesSize = numEntries * sizeof(lutEntry_t);
const size_t totalSize = headerSize + entriesSize;
Expand All @@ -133,10 +131,10 @@ void FlatLutData::initialize(const lutHeader_t& header)

size_t FlatLutData::getEntryOffset(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
{
static constexpr size_t headerSize = sizeof(lutHeader_t);
static constexpr size_t HeaderSize = sizeof(lutHeader_t);
const size_t linearIdx = getEntryIndex(nch_bin, rad_bin, eta_bin, pt_bin);
static constexpr size_t entrySize = sizeof(lutEntry_t);
return headerSize + linearIdx * entrySize;
static constexpr size_t EntrySize = sizeof(lutEntry_t);
return HeaderSize + linearIdx * EntrySize;
}

const lutEntry_t* FlatLutData::getEntryRef(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
Expand All @@ -153,12 +151,12 @@ lutEntry_t* FlatLutData::getEntry(int nch_bin, int rad_bin, int eta_bin, int pt_

const lutHeader_t& FlatLutData::getHeaderRef() const
{
return *reinterpret_cast<const lutHeader_t*>(mDataRef.data());
return *static_cast<const lutHeader_t*>(static_cast<const void*>(mDataRef.data()));
}

lutHeader_t& FlatLutData::getHeader()
{
return *reinterpret_cast<lutHeader_t*>(mData.data());
return *static_cast<lutHeader_t*>(static_cast<void*>(mData.data()));
}

void FlatLutData::updateRef()
Expand Down Expand Up @@ -200,26 +198,26 @@ void FlatLutData::view(const uint8_t* buffer, size_t size)

void FlatLutData::validateBuffer(const uint8_t* buffer, size_t size)
{
auto header = PreviewHeader(buffer, size);
auto mNchBins = header.nchmap.nbins;
auto mRadBins = header.radmap.nbins;
auto mEtaBins = header.etamap.nbins;
auto mPtBins = header.ptmap.nbins;
auto header = previewHeader(buffer, size);
const auto nchBins = header.nchmap.nbins;
const auto radBins = header.radmap.nbins;
const auto etaBins = header.etamap.nbins;
const auto ptBins = header.ptmap.nbins;

size_t expectedSize = sizeof(lutHeader_t) + static_cast<size_t>(mNchBins) * mRadBins * mEtaBins * mPtBins * sizeof(lutEntry_t);
const size_t expectedSize = sizeof(lutHeader_t) + static_cast<size_t>(nchBins) * radBins * etaBins * ptBins * sizeof(lutEntry_t);

if (size < expectedSize) {
throw framework::runtime_error_f("Buffer size mismatch: expected %zu, got %zu", expectedSize, size);
}
}

lutHeader_t FlatLutData::PreviewHeader(const uint8_t* buffer, size_t size)
lutHeader_t FlatLutData::previewHeader(const uint8_t* buffer, size_t size)
{
if (size < sizeof(lutHeader_t)) {
throw framework::runtime_error_f("Buffer too small for LUT header: expected at least %zu, got %zu", sizeof(lutHeader_t), size);
}
const auto* header = reinterpret_cast<const lutHeader_t*>(buffer);
if (!header->check_version()) {
const auto* header = static_cast<const lutHeader_t*>(static_cast<const void*>(buffer));
if (!header->checkVersion()) {
throw framework::runtime_error_f("LUT header version mismatch: expected %d, got %d", LUTCOVM_VERSION, header->version);
}
return *header;
Expand Down Expand Up @@ -256,14 +254,14 @@ bool FlatLutData::isLoaded() const
return ((!mData.empty()) || (!mDataRef.empty()));
}

lutHeader_t FlatLutData::PreviewHeader(std::ifstream& file, const char* filename)
lutHeader_t FlatLutData::previewHeader(std::ifstream& file, const char* filename)
{
lutHeader_t tempHeader;
file.read(reinterpret_cast<char*>(&tempHeader), sizeof(lutHeader_t));
if (file.gcount() != static_cast<std::streamsize>(sizeof(lutHeader_t))) {
throw framework::runtime_error_f("Failed to read LUT header from %s", filename);
}
if (!tempHeader.check_version()) {
if (!tempHeader.checkVersion()) {
throw framework::runtime_error_f("LUT header version mismatch: expected %d, got %d", LUTCOVM_VERSION, tempHeader.version);
}
return tempHeader;
Expand All @@ -272,7 +270,7 @@ lutHeader_t FlatLutData::PreviewHeader(std::ifstream& file, const char* filename
FlatLutData FlatLutData::loadFromFile(std::ifstream& file, const char* filename)
{
// Read header first
lutHeader_t tempHeader = PreviewHeader(file, filename);
lutHeader_t tempHeader = previewHeader(file, filename);

FlatLutData data;

Expand Down Expand Up @@ -300,4 +298,4 @@ void FlatLutData::reset()
resetDimensions();
}

} // namespace o2::delphes
} // namespace o2::fastsim
76 changes: 47 additions & 29 deletions ALICE3/Core/FlatLutEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,36 @@
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

/// \file FlatLutEntry.h
/// \brief Flat LUT data structures and buffer handling for the ALICE3 fast smearing backend.

#ifndef ALICE3_CORE_FLATLUTENTRY_H_
#define ALICE3_CORE_FLATLUTENTRY_H_

#include <array>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <span>
#include <vector>

#define LUTCOVM_VERSION 20210801
static constexpr int LUTCOVM_VERSION = 20210801;

namespace o2::delphes
namespace o2::fastsim
{

constexpr int kNumCovarianceTerms = 15;
constexpr int kNumEigenModes = 5;
typedef std::array<float, kNumCovarianceTerms> CovarianceArray;
typedef std::array<float, kNumEigenModes> EigenArray;
typedef std::array<double, kNumEigenModes> EigenArrayDouble;
typedef std::array<std::array<float, kNumEigenModes>, kNumEigenModes> EigenMatrix;

/**
* @brief Flat LUT entry structure
* @brief Flat LUT entry structure.
*/
struct lutEntry_t {
struct LutEntry {
float nch = 0.f;
float eta = 0.f;
float pt = 0.f;
Expand All @@ -36,41 +47,46 @@ struct lutEntry_t {
float eff2 = 0.f;
float itof = 0.f;
float otof = 0.f;
float covm[15] = {0.f};
float eigval[5] = {0.f};
float eigvec[5][5] = {{0.f}};
float eiginv[5][5] = {{0.f}};
CovarianceArray covm = {0.f};
EigenArray eigval = {0.f};
EigenMatrix eigvec = {{{0.f}}};
EigenMatrix eiginv = {{{0.f}}};

void print() const;
};

using lutEntry_t = LutEntry;

/**
* @brief Binning map
* @brief Binning map.
*/
struct map_t {
struct Map {
int nbins = 1;
float min = 0.f;
float max = 1.e6f;
bool log = false;

float eval(int bin) const
[[nodiscard]] float eval(int bin) const
{
float width = (max - min) / nbins;
float val = min + (bin + 0.5f) * width;
if (log)
if (log) {
return std::pow(10.f, val);
}
return val;
}

float fracPositionWithinBin(float val) const;
int find(float val) const;
[[nodiscard]] float fracPositionWithinBin(float val) const;
[[nodiscard]] int find(float val) const;
void print() const;
};

using map_t = Map;

/**
* @brief LUT header
* @brief LUT header.
*/
struct lutHeader_t {
struct LutHeader {
int version = LUTCOVM_VERSION;
int pdg = 0;
float mass = 0.f;
Expand All @@ -80,12 +96,14 @@ struct lutHeader_t {
map_t etamap;
map_t ptmap;

bool check_version() const;
[[nodiscard]] bool checkVersion() const;
void print() const;
};

using lutHeader_t = LutHeader;

/**
* @brief Flat LUT data container - single contiguous buffer
* @brief Flat LUT data container - single contiguous buffer.
* Memory layout: [header][entry_0][entry_1]...[entry_N]
*
* All entries stored sequentially in a single allocation.
Expand All @@ -104,7 +122,7 @@ class FlatLutData
*/
void initialize(const lutHeader_t& header);

size_t getEntryIndex(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
[[nodiscard]] size_t getEntryIndex(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const
{
// Linear index: nch varies slowest, pt varies fastest
// idx = nch * (rad*eta*pt) + rad * (eta*pt) + eta * pt + pt
Expand All @@ -114,7 +132,7 @@ class FlatLutData
/**
* @brief Get LUT entry by bin indices (view)
*/
const lutEntry_t* getEntryRef(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const;
[[nodiscard]] const lutEntry_t* getEntryRef(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const;

/**
* @brief Get LUT entry by bin indices (owned)
Expand All @@ -124,7 +142,7 @@ class FlatLutData
/**
* @brief Get LUT header (view)
*/
const lutHeader_t& getHeaderRef() const;
[[nodiscard]] const lutHeader_t& getHeaderRef() const;

/**
* @brief Get LUT header (owned)
Expand All @@ -134,13 +152,13 @@ class FlatLutData
/**
* @brief Get raw data buffer
*/
uint8_t* data() { return mData.data(); } // owned
const uint8_t* data() const { return mDataRef.data(); } // view
uint8_t* data() { return mData.data(); } // owned
[[nodiscard]] const uint8_t* data() const { return mDataRef.data(); } // view

/**
* @brief Total size in bytes
*/
size_t bytes() const { return mDataRef.size(); }
[[nodiscard]] size_t bytes() const { return mDataRef.size(); }

/**
* @brief Construct a new FlatLutData from external buffer as a copy
Expand All @@ -165,17 +183,17 @@ class FlatLutData
/**
* @brief Preview buffer header for version and other compatibility checks
*/
static lutHeader_t PreviewHeader(const uint8_t* buffer, size_t size);
static lutHeader_t previewHeader(const uint8_t* buffer, size_t size);

/**
* @brief Preview file-stored header for version and other compatibility checks
*/
static lutHeader_t PreviewHeader(std::ifstream& file, const char* filename);
static lutHeader_t previewHeader(std::ifstream& file, const char* filename);

/**
* @brief Check if the LUT is loaded
*/
bool isLoaded() const;
[[nodiscard]] bool isLoaded() const;

/**
* @brief Reset LUT to empty
Expand All @@ -186,7 +204,7 @@ class FlatLutData
/**
* @brief Linear index calculation for entry access
*/
size_t getEntryOffset(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const;
[[nodiscard]] size_t getEntryOffset(int nch_bin, int rad_bin, int eta_bin, int pt_bin) const;

/**
* @brief Update dimensions from the current header
Expand Down Expand Up @@ -224,6 +242,6 @@ class FlatLutData
int mPtBins = 0;
};

} // namespace o2::delphes
} // namespace o2::fastsim

#endif // ALICE3_CORE_FLATLUTENTRY_H_
Loading
Loading