15#ifndef ROOT_INTERNAL_ML_RCLUSTERLOADER
16#define ROOT_INTERNAL_ML_RCLUSTERLOADER
47 static_cast<std::size_t
>(
end -
start)};
59template <
typename... ColTypes>
74 template <typename T, std::enable_if_t<ROOT::Internal::RDF::IsDataContainer<T>::value,
int> = 0>
78 std::size_t vec_size = vec.size();
81 if (vec_size < max_vec_size)
83 std::copy(vec.begin(), vec.end(),
dst);
87 std::copy(vec.begin(), vec.begin() + max_vec_size,
dst);
94 template <typename T, std::enable_if_t<!ROOT::Internal::RDF::IsDataContainer<T>::value,
int> = 0>
103 const std::vector<std::size_t> &maxVecSizes,
float vecPadding,
int i,
104 std::size_t rowOffset = 0)
110 fOffset(rowOffset * numColumns)
148template <
typename... Args>
151 std::vector<ROOT::RDF::RNode> &
fRdfs;
178 RClusterLoader(std::vector<ROOT::RDF::RNode> &rdfs,
const std::vector<std::string> &cols,
179 const std::vector<std::size_t> &vecSizes,
float vecPadding,
float validationSplit,
bool shuffle,
193 for (
auto &rdf :
fRdfs) {
195 if (!rdf.GetFilterNames().empty()) {
205 for (std::size_t rdfIdx = 0; rdfIdx <
fRdfs.size(); ++rdfIdx) {
208 auto numEntries =
r.second -
r.first;
221 throw std::runtime_error(
"RClusterLoader::SplitDataset: no clusters found.");
234 std::uniform_int_distribution<int> coin(0, 1);
236 std::size_t cumulativeEntries = 0;
237 std::size_t currentCumulativeTrain = 0;
243 const std::size_t sz =
c.GetNumEntries();
244 cumulativeEntries += sz;
245 const std::size_t targetCumulativeTrain =
247 const std::size_t trainSz = targetCumulativeTrain - currentCumulativeTrain;
248 currentCumulativeTrain = targetCumulativeTrain;
249 const std::size_t valSz = sz - trainSz;
252 bool trainIsPrefix = coin(
g);
253 const uint64_t trainStart = trainIsPrefix ?
c.start :
c.start +
static_cast<std::uint64_t
>(valSz);
254 const uint64_t valStart = trainIsPrefix ?
c.start +
static_cast<std::uint64_t
>(trainSz) :
c.start;
257 fTrainingClusters.push_back({
c.rdfIdx, trainStart, trainStart +
static_cast<std::uint64_t
>(trainSz)});
261 fValidationClusters.push_back({
c.rdfIdx, valStart, valStart +
static_cast<std::uint64_t
>(valSz)});
272 std::size_t accumulated = 0;
273 std::size_t splitIdx = 0;
275 const std::size_t sz =
fAllClusters[splitIdx].GetNumEntries();
276 if (accumulated + sz > targetTraining) {
286 if (splitIdx <
fAllClusters.size() && accumulated < targetTraining) {
289 const std::uint64_t splitPoint = boundary.
start +
static_cast<std::uint64_t
>(targetTraining - accumulated);
305 throw std::runtime_error(
"RClusterLoader::SplitDataset: no entries for training after split. "
306 "Reduce validation_split.");
309 throw std::runtime_error(
"RClusterLoader::SplitDataset: no entries for validation after split. "
310 "Increase validation_split.");
337 std::size_t rowOffset = 0)
361 std::uint64_t endRow, std::size_t rowOffset = 0)
366 std::vector<ROOT::RDF::RResultPtr<ULong64_t>> counts;
367 counts.reserve(
fRdfs.size());
368 for (
auto &rdf :
fRdfs) {
369 counts.push_back(rdf.Count());
373 std::size_t totalFiltered = 0;
374 for (
auto &
c : counts) {
375 totalFiltered +=
c.GetValue();
383 std::vector<ULong64_t> rdfEntries;
384 rdfEntries.reserve(endRow - startRow);
387 rdf.
Foreach([&](
ULong64_t entry) { rdfEntries.push_back(entry); }, {
"rdfentry_"});
390 const std::size_t totalFiltered = rdfEntries.size();
391 if (totalFiltered == 0) {
394 std::sort(rdfEntries.begin(), rdfEntries.end());
396 const std::size_t cumulativeFiltered =
398 const std::size_t targetCumulativeTrain =
401 const std::size_t valCount = totalFiltered - trainCount;
403 bool trainIsPrefix =
true;
408 std::uniform_int_distribution<int> coin(0, 1);
409 trainIsPrefix = coin(
g);
418 std::uint64_t boundary;
421 boundary = (trainCount < totalFiltered) ? rdfEntries[trainCount] : endRow;
424 boundary = (valCount < totalFiltered) ? rdfEntries[valCount] : endRow;
427 const std::uint64_t trainStart = trainIsPrefix ? startRow : boundary;
428 const std::uint64_t trainEnd = trainIsPrefix ? boundary : endRow;
429 const std::uint64_t valStart = trainIsPrefix ? boundary : startRow;
430 const std::uint64_t valEnd = trainIsPrefix ? endRow : boundary;
447 return endRow - startRow;
453 std::size_t rowOffset = 0)
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Functor invoked by RDataFrame::Foreach to fill one row of an RFlat2DMatrix.
std::size_t fNumChunkCols
void AssignToTensor(const T &vec, int i, int numColumns)
Copy the content of a column into the current tensor when the column consists of vectors.
RFlat2DMatrix & fChunkTensor
RClusterLoaderFunctor(RFlat2DMatrix &chunkTensor, std::size_t numColumns, const std::vector< std::size_t > &maxVecSizes, float vecPadding, int i, std::size_t rowOffset=0)
void AssignToTensor(const T &val, int i, int numColumns)
Copy the content of a column into the current tensor when the column consists of scalar values.
void operator()(const ColTypes &...cols)
std::vector< std::size_t > fMaxVecSizes
Loads TTree/RNTuple clusters from one or more RDataFrames into RFlat2DMatrix buffers for ML training ...
std::size_t GetNumValidationClusters() const
std::size_t fNumValidationEntries
void ShuffleTrainingClusters(std::size_t epochIdx)
Re-order training clusters for the upcoming epoch.
void FinaliseSplitDiscovery()
Mark the train/val split as finalised after the first epoch.
std::size_t fAccumulatedFilteredForTrain
std::size_t fNumTrainingEntries
void LoadClusterInto(RFlat2DMatrix &dest, std::size_t rdfIdx, std::uint64_t startRow, std::uint64_t endRow, std::size_t rowOffset=0)
std::vector< std::size_t > fRdfSizes
void ShuffleValidationClusters(std::size_t epochIdx)
Re-order validation clusters for the upcoming epoch.
std::size_t fNumChunkCols
std::size_t LoadTrainingClusterInto(RFlat2DMatrix &dest, std::size_t rdfIdx, std::uint64_t startRow, std::uint64_t endRow, std::size_t rowOffset=0)
Load one training cluster and return the number of rows written.
std::size_t GetNumTrainingClusters() const
std::vector< RClusterRange > fAllClusters
void SplitDataset()
Distribute the clusters into training and validation datasets No-op for filtered RDataFrames,...
void LoadValidationClusterInto(RFlat2DMatrix &dest, std::size_t rdfIdx, std::uint64_t startRow, std::uint64_t endRow, std::size_t rowOffset=0)
Load one validation cluster into dest starting at rowOffset.
const std::vector< RClusterRange > & GetTrainingClusters() const
std::size_t fTotalEntries
std::size_t GetNmTotalClusters() const
std::size_t fAccumulatedFilteredForVal
RClusterLoader(std::vector< ROOT::RDF::RNode > &rdfs, const std::vector< std::string > &cols, const std::vector< std::size_t > &vecSizes, float vecPadding, float validationSplit, bool shuffle, std::size_t setSeed)
const std::vector< RClusterRange > & GetValidationClusters() const
bool IsSplitDiscovered() const
std::size_t GetNumValidationEntries() const
std::size_t GetNumTrainingEntries() const
std::vector< std::size_t > fVecSizes
std::vector< RClusterRange > fValidationClusters
std::vector< ROOT::RDF::RNode > & fRdfs
std::vector< std::string > fCols
std::size_t GetNumChunkCols() const
std::vector< RClusterRange > fTrainingClusters
The public interface to the RDataFrame federation of classes.
void Foreach(F f, const ColumnNames_t &columns={})
Execute a user-defined function on each entry (instant action).
std::vector< std::pair< std::uint64_t, std::uint64_t > > GetDatasetGlobalClusterBoundaries(const RNode &node)
Retrieve the cluster boundaries for each cluster in the dataset, across files, with a global offset.
void ChangeBeginAndEndEntries(const RNode &node, Long64_t begin, Long64_t end)
unsigned int RunGraphs(std::vector< RResultHandle > handles)
Run the event loops of multiple RDataFrames concurrently.
Describes a contiguous range of entries within a single RDataFrame, corresponding to one TTree/RNTupl...
std::size_t GetNumEntries() const
void SetNumEntries(std::size_t num)
Wrapper around ROOT::RVec<float> representing a 2D matrix.