Dear experts,
We use RVec operations in our analysis and we let the JIT to interpret
Scalar (*,-,+,/) Vector operations or Vector to Vector
Everything works very nicely, however we have not been able to get a JITTED code working fine for
TMath::Max( Scalar * Vector , Scalar * Vector)
columns .
I wonder if there is any inline thing we can declare to get this working fine or we should decouple the 2 elements in the comparison expression ad replace this with a set of 2Defines and one operator() which does a new RVec with the indexes.
I know this is not “general” enough as one can say the Vector columns are not equal sized, but in our analysis this is the case.
Any suggestion is welcome.
Ideally i would be interested to understand as well, if i can declare actually a custom namespace with some inlined functions which can be jitted , that would be awesome, but i fail to understand what to add to LinkDef and how to actually declare that function (in case), something like this for example :
namespace TMath{
inline ROOT::VecOps::RVec<double> Max( ROOT::VecOps::RVec<double> & a, ROOT::VecOps::RVec<double> & b ){
ROOT::VecOps::RVec<double> vecOut;
for( int i = 0 ; i < a.size() ; ++i){
if( a.at(i) > b.at(i)) vecOut.push_back( a.at(i));
else vecOut.push_back( b.at(i));
}
return vecOut;
};
inline ROOT::VecOps::RVec<float> Max( ROOT::VecOps::RVec<float> & a, ROOT::VecOps::RVec<float> & b ){
ROOT::VecOps::RVec<float> vecOut;
for( int i = 0 ; i < a.size() ; ++i){
if( a.at(i) > b.at(i)) vecOut.push_back( a.at(i));
else vecOut.push_back( b.at(i));
}
return vecOut;
};
};
Hi, TMath::Max is only defined for scalars.
You can add an overload for RVecs, it should be enough to pass the code you mentioned to gInterpreter->Declare, although adding things to another library’s namespace is usually considered “unsafe” (as that library might then also define the same thing, creating conflicts. but ROOT will likely never define RVec-oriented overloads of TMath stuff).
max(vector<double>, vector<double>) is not a vectorized version of max: it returns either the first or the second vector depending on the value of vec1 < vec2 (which I’m surprised it’s defined).
Thanks @eguiraud , so if i have a CMake project, it would be enough to add in my executable which i compile
gInterpreter->Declare("… c++ code for the function") ?
Cheers
Renato
gInterpreter->Declare("ROOT::VecOps::RVec<double> MAXV( ROOT::VecOps::RVec<double> & a, ROOT::VecOps::RVec<double> & b ){ "
" ROOT::VecOps::RVec<double> vecOut; "
" for( int i = 0 ; i < a.size() ; ++i){ "
" if( a.at(i) > b.at(i)) vecOut.push_back( a.at(i)); "
" else vecOut.push_back( b.at(i)); "
" } "
" return vecOut; "
"};");
is added in my code , when the Define using MAXV is called
input_line_180:13:57: error: no matching function for call to 'MAXV'
return RndPoisson2*(wiPIDCalib_Weight_BS*wTRKCalib_BS*((MAXV(E1_wfL0L_comb_Bp_effCL_BS*(E1_L0Calo_ECAL_realET>3000.000000),E2_wfL0L_comb_Bp_effCL_BS*(E2_L0Calo_ECAL_realET>3000.000000)))/(MAXV(E1_wfL0L_comb_Bp_effMC_BS*(E1...
^~~~
input_line_105:1:28: note: candidate function not viable: expects an l-value for 1st argument
ROOT::VecOps::RVec<double> MAXV( ROOT::VecOps::RVec<double> & a, ROOT::VecOps::RVec<double> & b ){ ROOT::VecOps::RVec<double> vecOut; for( int i = 0 ; i ...
^