7 #pragma GCC diagnostic ignored "-Wuseless-cast"
28 const std::vector<RespFuncType> &SplineType,
29 const bool SaveFlatTree,
30 const std::string& _FastSplineName,
62 MACH3LOG_INFO(
"Found {} maximum number of splines in an event", maxnSplines);
106 unsigned int KnotCounter = 0;
107 unsigned int TF1PointsCounter = 0;
108 unsigned int NSplinesCounter = 0;
109 unsigned int TF1sCounter = 0;
110 int ParamCounter = 0;
111 int ParamCounterGlobal = 0;
112 int ParamCounter_TF1 = 0;
113 int ParamCounterGlobalTF1 = 0;
115 for(
unsigned int EventCounter = 0; EventCounter < MasterSpline.size(); ++EventCounter) {
118 for(
unsigned int ParamNumber = 0; ParamNumber < MasterSpline[EventCounter].size(); ++ParamNumber) {
120 if (MasterSpline[EventCounter][ParamNumber] ==
nullptr)
continue;
134 if (nPoints_tmp == 1)
continue;
139 for (
int j = 0; j < nPoints_tmp; ++j) {
140 for (
int k = 0; k <
_nCoeff_; k++) {
148 KnotCounter += nPoints_tmp;
154 else if (SplineType[ParamNumber] ==
kTF1_red)
159 TF1_red* CurrSpline =
dynamic_cast<TF1_red*
>(MasterSpline[EventCounter][ParamNumber]);
169 TF1PointsCounter += nPoints_tmp;
178 delete MasterSpline[EventCounter][ParamNumber];
179 MasterSpline[EventCounter][ParamNumber] =
nullptr;
184 ParamCounterGlobal += ParamCounter;
188 ParamCounterGlobalTF1 += ParamCounter_TF1;
191 ParamCounter_TF1 = 0;
195 delete[] temp_coeffs;
198 for (
unsigned int j = 0; j < event_size_max; j++) {
203 MACH3LOG_WARN(
"Indicates some parameter doesn't have a single spline");
207 if(BadXCounter == 5)
MACH3LOG_WARN(
"There is more unutilised knots although I will stop spamming");
236 MACH3LOG_INFO(
"Total size = {:.2f} MB memory on CPU to move to GPU",
237 (
double(
sizeof(
float) *
nKnots *
_nCoeff_) +
double(
sizeof(
float) * event_size_max) / 1.E6 +
239 MACH3LOG_INFO(
"Total TF1 size = {:.2f} MB memory on CPU to move to GPU",
242 MACH3LOG_INFO(
"Since you are running Total event weight mode then GPU weight array (GPU->CPU every step) = {:.2f} MB",
243 double(
sizeof(
float) *
NEvents) / 1.E6);
244 MACH3LOG_INFO(
"Parameter value array (CPU->GPU every step) = {:.4f} MB",
double(
sizeof(
float) *
nParams) / 1.E6);
300 unsigned int &nEvents,
301 short int &MaxPoints,
302 short int &numParams,
304 unsigned int &NSplinesValid,
305 unsigned int &numKnots,
306 unsigned int &nTF1Valid,
307 unsigned int &nTF1_coeff,
308 const std::vector<RespFuncType> &SplineType) {
323 nEvents = int(MasterSpline.size());
326 int nMaxSplines_PerEvent = 0;
329 numParams = short(MasterSpline[0].size());
334 for(
unsigned int EventCounter = 0; EventCounter < MasterSpline.size(); ++EventCounter) {
337 int TempSize = int(MasterSpline[EventCounter].size());
338 if (TempSize != numParams) {
339 MACH3LOG_ERROR(
"Found {} parameters for event {}", TempSize, EventCounter);
340 MACH3LOG_ERROR(
"but was expecting {} since that's what I found for the previous event", numParams);
341 MACH3LOG_ERROR(
"Somehow this event has a different number of spline parameters... Please study further!");
345 numParams = short(MasterSpline[EventCounter].size());
347 int nSplines_SingleEvent = 0;
350 for(
unsigned int ParamNumber = 0; ParamNumber < MasterSpline[EventCounter].size(); ++ParamNumber) {
351 if (MasterSpline[EventCounter][ParamNumber]) {
357 nPoints = CurrSpline->
GetNp();
360 if (nPoints > MaxPoints) {
361 MaxPoints =
static_cast<short int>(nPoints);
364 nSplines_SingleEvent++;
378 CurrSpline->
GetKnot(k, xtemp, ytemp);
384 else if (SplineType[ParamNumber] ==
kTF1_red)
388 nPoints = CurrSpline->
GetSize();
389 nTF1_coeff += nPoints;
397 if (nSplines_SingleEvent > nMaxSplines_PerEvent) nMaxSplines_PerEvent = nSplines_SingleEvent;
399 nSplines = nMaxSplines_PerEvent;
403 for (
M3::int_t i = 0; i < numParams; ++i)
406 if (SplineType[i] ==
kTF1_red)
continue;
410 if (nPoints == -999 || xArray.size() == 0) {
419 MACH3LOG_WARN(
"In total SplineInfoArray for {} hasn't been initialised", Counter);
428 MACH3LOG_INFO(
"-- GPUING WITH {X} and {Y,B,C,D} arrays and master spline containing TSpline3_red");
438 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"OPEN");
439 TTree *Settings = SplineFile->Get<TTree>(
"Settings");
440 TTree *Monolith_TF1 = SplineFile->Get<TTree>(
"Monolith_TF1");
441 TTree *
EventInfo = SplineFile->Get<TTree>(
"EventInfo");
442 TTree *SplineTree = SplineFile->Get<TTree>(
"SplineTree");
444 unsigned int NEvents_temp;
445 short int nParams_temp;
447 unsigned int nKnots_temp;
448 unsigned int NSplines_valid_temp;
449 unsigned int nTF1Valid_temp;
450 unsigned int nTF1coeff_temp;
452 Settings->SetBranchAddress(
"NEvents", &NEvents_temp);
453 Settings->SetBranchAddress(
"nParams", &nParams_temp);
454 Settings->SetBranchAddress(
"_max_knots", &_max_knots_temp);
455 Settings->SetBranchAddress(
"nKnots", &nKnots_temp);
456 Settings->SetBranchAddress(
"NSplines_valid", &NSplines_valid_temp);
457 Settings->SetBranchAddress(
"NTF1_valid", &nTF1Valid_temp);
458 Settings->SetBranchAddress(
"nTF1coeff", &nTF1coeff_temp);
460 Settings->GetEntry(0);
464 _max_knots =
static_cast<short int>(_max_knots_temp);
481 SplineTree->SetBranchAddress(
"SplineObject", &
cpu_monolith);
482 SplineTree->GetEntry(0);
484 float coeff_tf1 = 0.;
485 Monolith_TF1->SetBranchAddress(
"cpu_coeff_TF1_many", &coeff_tf1);
486 for(
unsigned int i = 0; i <
nTF1coeff; i++)
488 Monolith_TF1->GetEntry(i);
492 unsigned int nParamPerEvent = 0;
493 unsigned int nParamPerEvent_tf1 = 0;
495 EventInfo->SetBranchAddress(
"cpu_nParamPerEvent", &nParamPerEvent);
496 EventInfo->SetBranchAddress(
"cpu_nParamPerEvent_tf1", &nParamPerEvent_tf1);
497 for(
unsigned int i = 0; i < 2*
NEvents; i++)
522 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"recreate");
523 TTree *Settings =
new TTree(
"Settings",
"Settings");
524 TTree *Monolith_TF1 =
new TTree(
"Monolith_TF1",
"Monolith_TF1");
525 TTree *XKnots =
new TTree(
"XKnots",
"XKnots");
526 TTree *
EventInfo =
new TTree(
"EventInfo",
"EventInfo");
528 unsigned int NEvents_temp =
NEvents;
529 short int nParams_temp =
nParams;
531 unsigned int nKnots_temp =
nKnots;
536 Settings->Branch(
"NEvents", &NEvents_temp,
"NEvents/i");
537 Settings->Branch(
"nParams", &nParams_temp,
"nParams/S");
538 Settings->Branch(
"_max_knots", &_max_knots_temp,
"_max_knots/I");
539 Settings->Branch(
"nKnots", &nKnots_temp,
"nKnots/i");
540 Settings->Branch(
"NSplines_valid", &NSplines_valid_temp,
"NSplines_valid/i");
541 Settings->Branch(
"NTF1_valid", &nTF1Valid_temp,
"NTF1_valid/i");
542 Settings->Branch(
"nTF1coeff", &nTF1coeff_temp,
"nTF1coeff/i");
549 TTree *SplineTree =
new TTree(
"SplineTree",
"SplineTree");
556 float coeff_tf1 = 0.;
557 Monolith_TF1->Branch(
"cpu_coeff_TF1_many", &coeff_tf1,
"cpu_coeff_TF1_many/F");
558 for(
unsigned int i = 0; i <
nTF1coeff; i++)
561 Monolith_TF1->Fill();
564 Monolith_TF1->Write();
566 unsigned int nParamPerEvent = 0;
567 unsigned int nParamPerEvent_tf1 = 0;
569 EventInfo->Branch(
"cpu_nParamPerEvent", &nParamPerEvent,
"cpu_nParamPerEvent/i");
570 EventInfo->Branch(
"cpu_nParamPerEvent_tf1", &nParamPerEvent_tf1,
"cpu_nParamPerEvent_tf1/i");
572 for(
unsigned int i = 0; i < 2*
NEvents; i++)
623 for (
int j = 0; j <
_nCoeff_; j++) {
628 int Np = spl->
GetNp();
635 MACH3LOG_ERROR(
"This _WILL_ cause problems with GPU splines and _SHOULD_ be fixed!");
644 for(
int i = 0; i < Np; i++) {
648 xArray[i] = float(x);
653 if((xArray[i] == -999) || (manyArray[i*
_nCoeff_] == -999) || (manyArray[i*
_nCoeff_ +1] == -999) || (manyArray[i*
_nCoeff_+2] == -999) || (manyArray[i*
_nCoeff_+3] == -999)){
654 MACH3LOG_ERROR(
"*********** Bad params in {} ************", __func__);
655 MACH3LOG_ERROR(
"pre cast to float (x, y, b, c, d) = {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}", x, y, b, c, d);
656 MACH3LOG_ERROR(
"pre cast to float (x, y, b, c, d) = {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}", xArray[i], manyArray[i*
_nCoeff_], manyArray[i*
_nCoeff_+1], manyArray[i*
_nCoeff_+2], manyArray[i*
_nCoeff_+3]);
657 MACH3LOG_ERROR(
"This will cause problems when preparing for GPU");
658 MACH3LOG_ERROR(
"***************************************************************");
704 #pragma omp for simd nowait
706 for (
unsigned int splineNum = 0; splineNum <
NSplines_valid; ++splineNum)
715 const short int segment_X = short(Param*
_max_knots+segment);
738 for (
unsigned int tf1Num = 0; tf1Num <
NTF1_valid; ++tf1Num)
744 const unsigned int TF1_Index = tf1Num *
_nTF1Coeff_;
763 #pragma omp parallel for
765 for (
unsigned int EventNum = 0; EventNum <
NEvents; ++EventNum)
767 float totalWeight = 1.0f;
769 const unsigned int Offset = 2 * EventNum;
777 #pragma omp simd reduction(*:totalWeight)
779 for (
unsigned int id = 0;
id < numParams; ++id) {
789 #pragma omp simd reduction(*:totalWeight)
791 for (
unsigned int id = 0;
id < numParams_tf1; ++id) {
809 MACH3LOG_INFO(
"Size of x array = {:.4f} MB",
double(
sizeof(
float)*event_size_max)/1.E6);
@ kTF1_red
Uses TF1_red for interpolation.
@ kTSpline3_red
Uses TSpline3_red for interpolation.
void CleanVector(T &)
Base case: do nothing for non-vector types.
constexpr int _nCoeff_
KS: We store coefficients {y,b,c,d} in one array one by one, this is only to define it once rather th...
constexpr int _nTF1Coeff_
KS: For TF1 we store at most 5 coefficients, we could make it more flexible but for now define it her...
Custom exception class used throughout MaCh3.
Base class for calculating weight from spline.
SplineMonolithGPU * gpu_monolith
KS: Store info about Spline monolith, this allow to obtain better step time. As all necessary informa...
void GetTF1Coeff(TF1_red *&spl, int &nPoints, float *&coeffs) const
CW: Gets the polynomial coefficients for TF1.
unsigned int NSplines_valid
Number of valid splines.
short int nParams
Number of parameters that have splines.
short int _max_knots
Max knots for production.
void FindSplineSegment()
CW:Code used in step by step reweighting, Find Spline Segment for each param.
short int * SplineSegments
std::vector< FastSplineInfo > SplineInfoArray
float * ParamValues
Store parameter values they are not in FastSplineInfo as in case of GPU we need to copy paste it to G...
bool useGPU
Whether to use GPU or not.
void LoadFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed FastSplineInfo.
void PrepareFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Fast Spline Info within SplineFile.
void SetupSegments()
Since we find segment before actual reweight and sometimes we want to copy it to GPU we have differen...
Class responsible for calculating spline weight on GPU.
__host__ void InitGPU_SplineMonolith(unsigned int total_nknots, unsigned int n_splines, unsigned int n_tf1, int Eve_size)
Allocate memory on gpu for spline monolith.
__host__ void RunGPU_SplineMonolith_Unbinned(M3::float_t *cpu_total_weights, float *vals, short int *segment)
Run the GPU code for the separate many arrays. As in separate {x}, {y,b,c,d} arrays Pass the segment ...
__host__ void CleanupPinnedMemory(M3::float_t *cpu_total_weights, short int *segment, float *vals)
Clean up pinned variables at CPU.
__host__ void CopyToGPU_SplineMonolith_Unbinned(const SplineMonoStruct *cpu_spline_handler, const std::vector< float > &cpu_many_array_TF1, const std::vector< short int > &cpu_paramNo_arr_TF1, const int n_events, const std::vector< unsigned int > &cpu_nParamPerEvent, const std::vector< unsigned int > &cpu_nParamPerEvent_TF1, const int n_params, const unsigned int n_splines, const short int spline_size, const unsigned int total_nknots, const unsigned int n_tf1)
Copies data from CPU to GPU for the spline monolith.
__host__ void InitGPU_Unbinned_SplineMonolith(M3::float_t **cpu_total_weights, int n_events)
Allocate memory on gpu for spline monolith.
CW: A reduced TF1 class only. Only saves parameters for each TF1 and how many parameters each paramet...
int GetSize() const
Get the size.
KS: A reduced ResponseFunction Generic function used for evaluating weight.
CW: Reduced TSpline3 class.
void GetKnot(int i, M3::float_t &xtmp, M3::float_t &ytmp) const
void GetCoeff(int segment, M3::float_t &x, M3::float_t &y, M3::float_t &b, M3::float_t &c, M3::float_t &d) const
CW: Get the coefficient of a given segment.
M3::int_t GetNp() const override
CW: Get the number of points.
float * cpu_weights_tf1_var
CPU arrays to hold weight for each TF1.
float * cpu_weights_spline_var
CPU arrays to hold weight for each spline.
unsigned int nTF1coeff
Sum of all coefficients over all TF1.
unsigned int NTF1_valid
Number of valid TF1.
void ScanMasterSpline(std::vector< std::vector< TResponseFunction_red * > > &MasterSpline, unsigned int &nEvents, short int &MaxPoints, short int &numParams, int &nSplines, unsigned int &NSplinesValid, unsigned int &numKnots, unsigned int &nTF1Valid, unsigned int &nTF1_coeff, const std::vector< RespFuncType > &SplineType)
CW: Function to scan through the MasterSpline of TSpline3.
void PrepareSplineFile(std::string FileName) final
KS: Prepare spline file that can be used for fast loading.
std::vector< unsigned int > cpu_nParamPerEvent
KS: CPU map keeping track how many parameters applies to each event, we keep two numbers here {number...
void Evaluate() final
CW: This Eval should be used when using two separate x,{y,a,b,c,d} arrays to store the weights; proba...
std::vector< short int > cpu_paramNo_TF1_arr
CW: CPU array with the number of points per spline (not per spline point!)
void PrintInitialsiation() const
KS: Print info about how much knots etc has been initialised.
std::vector< unsigned int > cpu_nParamPerEvent_tf1
KS: CPU map keeping track how many parameters applies to each event, we keep two numbers here {number...
SplineMonoStruct * cpu_monolith
KS: Store info about Spline monolith, this allow to obtain better step time. As all necessary informa...
void MoveToGPU()
CW: The shared initialiser from constructors of TResponseFunction_red.
unsigned int nKnots
Sum of all knots over all splines.
void CalcSplineWeights() final
CPU based code which eval weight for each spline.
UnbinnedSplineHandler(std::vector< std::vector< TResponseFunction_red * > > &MasterSpline, const std::vector< RespFuncType > &SplineType, const bool SaveFlatTree=false, const std::string &_FastSplineName="SplineFile.root", const bool Use_GPU=true)
Constructor.
std::vector< short int > cpu_nPoints_arr
CPU arrays to hold number of points.
void PrepareForGPU(std::vector< std::vector< TResponseFunction_red * > > &MasterSpline, const std::vector< RespFuncType > &SplineType)
CW: Prepare the TSpline3_red objects for the GPU.
void Initialise()
KS: Set everything to null etc.
void LoadSplineFile(std::string FileName) final
KS: Load preprocessed spline file.
virtual ~UnbinnedSplineHandler()
Destructor for UnbinnedSplineHandler class.
std::vector< float > cpu_coeff_TF1_many
CPU arrays to hold TF1 coefficients.
void GetSplineCoeff_SepMany(TSpline3_red *&spl, int &nPoints, float *&xArray, float *&manyArray) const
CW: This loads up coefficients into two arrays: one x array and one yabcd array.
M3::float_t * cpu_total_weights
KS: This holds the total CPU weights that gets read in SampleHandler.
bool SaveSplineFile
Flag telling whether we are saving spline monolith into handy root file.
unsigned int NEvents
Number of events.
std::string FastSplineName
Name of Fast Spline to which will be saved.
void CalcTotalEventWeight()
Calc total event weight.
MaCh3 event-by-event cross-section spline code.
void AddPath(std::string &FilePath)
Prepends the MACH3 environment path to FilePath if it is not already present.
Stores info about each MC event used during reweighting routine.
KS: Struct storing information for spline monolith.
std::vector< unsigned int > nKnots_arr
KS: CPU Number of knots per spline.
std::vector< float > coeff_x
KS: CPU arrays to hold X coefficient.
std::vector< float > coeff_many
CPU arrays to hold other coefficients.
std::vector< short int > paramNo_arr
CW: CPU array with the number of points per spline (not per spline point!)