Skip to content

Add codegen support for VerticalInterpPdf #1060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

runtingt
Copy link
Contributor

@runtingt runtingt commented Mar 31, 2025

Refactors the mathematical details of vertical interpolation into free functions and implements the required translate and impl functions to support the codegen backend

To be merged after #1019

@runtingt runtingt marked this pull request as draft March 31, 2025 15:30
@runtingt runtingt marked this pull request as ready for review March 31, 2025 15:59
@runtingt runtingt force-pushed the roofit_ad_dev branch 2 times, most recently from fa79af8 to 73023df Compare April 1, 2025 07:25
@vgvassilev
Copy link

@runtingt, can you rebase this PR?

@vgvassilev
Copy link

@mcbarton, do you have a clue why clang-tidy does not comment in this PR?

@runtingt
Copy link
Contributor Author

runtingt commented Apr 8, 2025

@mcbarton, do you have a clue why clang-tidy does not comment in this PR?

If it helps (as I can't actually seem to find it linked to this PR anywhere under Checks), here's the run: https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/actions/runs/14328764810/job/40159694791#step:3:654

@vgvassilev
Copy link

Ok, looks like we hit ZedThree/clang-tidy-review#144

@vgvassilev
Copy link

@runtingt it was recently fixed and released under 0.21 -- can you update

as part of this PR to see if it works?

@mcbarton
Copy link
Contributor

mcbarton commented Apr 8, 2025

Not entirely sure why its not commenting from a quick look, since it worked in my dummy PR. One thing which does need to be fixed about the workflow is to activate it for more file changes. If you look here https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/blob/228c0a0bd2d7729c9d550915e0418f997a4d97ea/.github/workflows/clang-tidy-review.yml#L6C1-L7C16 it only activates when PRs change .cc and .h files, but not for .cxx files.

@mcbarton
Copy link
Contributor

mcbarton commented Apr 8, 2025

The comments are clearly created here https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/actions/runs/14337808458/job/40189300120?pr=1060#step:7:1168 . No idea why they are not posting. After I allowed actions to run on my fork, all I needed to do was open up the PR for it to work, as can be seen in the dummy PR here mcbarton#2 (review) . My only guess is that the something with the settings of the repo is not quite right. Mine were whatever the default was, plus allowing actions to run.

@runtingt
Copy link
Contributor Author

runtingt commented Apr 8, 2025

@mcbarton In the case of your dummy PR, the workflow already exists on the target branch. I think in order to use the patched v0.21.0, this needs to be present on the target branch already

@mcbarton
Copy link
Contributor

mcbarton commented Apr 8, 2025

@mcbarton In the case of your dummy PR, the workflow already exists on the target branch. I think in order to use the patched v0.21.0, this needs to be present on the target branch already

@runtingt The action already exists on the target branch, its just not the latest version. Only way to find out if the target branch has to have the new version for it to work would be to open up a separate PR with the clang tidy fixes, get it merged, and then rebase this PR. I'd also suggest making this change in the clang tidy PR #1060 (comment) , since its another issue with the workflow.


if (fabs(coeff) >= quadraticRegion) {
return coeff * (coeff > 0 ? fUp - central : central - fDn);
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the else part because of the return.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise for the other else parts that the if-conditional has a return.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 10 out of 37. Check the log or trigger a new build to see more.

@@ -2,17 +2,28 @@
#define HiggsAnalysis_CombinedLimit_CombineCodegenImpl_h

#include <ROOT/RConfig.hxx> // for ROOT_VERSION
#include <RooAbsReal.h>
#include <string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header RooAbsReal.h is not used directly [misc-include-cleaner]

Suggested change
#include <string>
#include <string>

@@ -2,17 +2,28 @@
#define HiggsAnalysis_CombinedLimit_CombineCodegenImpl_h

#include <ROOT/RConfig.hxx> // for ROOT_VERSION
#include <RooAbsReal.h>
#include <string>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header string is not used directly [misc-include-cleaner]

Suggested change

@@ -145,6 +150,161 @@ inline double processNormalization(double nominalValue, std::size_t nThetas, std
return norm;
}

// Interpolation (from VerticalInterpPdf)
inline Double_t interpolate(Double_t const coeff, Double_t const central, Double_t const fUp,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "Double_t" is directly included [misc-include-cleaner]

interface/CombineMathFuncs.h:7:

+ #include <RtypesCore.h>

@@ -145,6 +150,161 @@ inline double processNormalization(double nominalValue, std::size_t nThetas, std
return norm;
}

// Interpolation (from VerticalInterpPdf)
inline Double_t interpolate(Double_t const coeff, Double_t const central, Double_t const fUp,
Double_t const fDn, Double_t const quadraticRegion, Int_t const quadraticAlgo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "Int_t" is directly included [misc-include-cleaner]

                            Double_t const fDn, Double_t const quadraticRegion, Int_t const quadraticAlgo)
                                                                                ^

Double_t c_up = + coeff * (quadraticRegion + coeff) / (2 * quadraticRegion);
Double_t c_dn = - coeff * (quadraticRegion - coeff) / (2 * quadraticRegion);
Double_t c_cen = - coeff * coeff / quadraticRegion;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
return c_up * fUp + c_dn * fDn + c_cen * central;
return (c_up * fUp) + c_dn * fDn + c_cen * central;

Double_t c_up = + coeff * (quadraticRegion + coeff) / (2 * quadraticRegion);
Double_t c_dn = - coeff * (quadraticRegion - coeff) / (2 * quadraticRegion);
Double_t c_cen = - coeff * coeff / quadraticRegion;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
return c_up * fUp + c_dn * fDn + c_cen * central;
return c_up * fUp + (c_dn * fDn) + c_cen * central;

Double_t c_up = + coeff * (quadraticRegion + coeff) / (2 * quadraticRegion);
Double_t c_dn = - coeff * (quadraticRegion - coeff) / (2 * quadraticRegion);
Double_t c_cen = - coeff * coeff / quadraticRegion;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
return c_up * fUp + c_dn * fDn + c_cen * central;
return c_up * fUp + c_dn * fDn + (c_cen * central);

Double_t c_up = (quadraticRegion + coeff) * (quadraticRegion + coeff) / (4 * quadraticRegion);
Double_t c_dn = (quadraticRegion - coeff) * (quadraticRegion - coeff) / (4 * quadraticRegion);
Double_t c_cen = - c_up - c_dn;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

      return c_up * fUp + c_dn * fDn + c_cen * central;
                                       ^

this fix will not be applied because it overlaps with another fix

Double_t c_up = (quadraticRegion + coeff) * (quadraticRegion + coeff) / (4 * quadraticRegion);
Double_t c_dn = (quadraticRegion - coeff) * (quadraticRegion - coeff) / (4 * quadraticRegion);
Double_t c_cen = - c_up - c_dn;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

      return c_up * fUp + c_dn * fDn + c_cen * central;
                          ^

this fix will not be applied because it overlaps with another fix

Double_t c_up = (quadraticRegion + coeff) * (quadraticRegion + coeff) / (4 * quadraticRegion);
Double_t c_dn = (quadraticRegion - coeff) * (quadraticRegion - coeff) / (4 * quadraticRegion);
Double_t c_cen = - c_up - c_dn;
return c_up * fUp + c_dn * fDn + c_cen * central;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

      return c_up * fUp + c_dn * fDn + c_cen * central;
             ^

this fix will not be applied because it overlaps with another fix

@runtingt
Copy link
Contributor Author

runtingt commented Apr 9, 2025

@vgvassilev @mcbarton Looks like updating main worked - I'll go through these suggestions

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Double_t const pdfFloorVal, Double_t const quadraticRegion, Int_t const quadraticAlgo)
{
// Do running sum of coef/func pairs, calculate lastCoef.
Double_t central = funcList[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

   Double_t central = funcList[0];
                      ^

Double_t value = central;

for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double coefVal = coefList[iCoef];
                       ^


for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
double funcUp = funcList[(2 * iCoef) + 1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double funcUp = funcList[(2 * iCoef) + 1];
                      ^

for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
double funcUp = funcList[(2 * iCoef) + 1];
double funcDn = funcList[(2 * iCoef) + 2];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double funcDn = funcList[(2 * iCoef) + 2];
                      ^

Double_t const pdfFloorVal, Double_t const quadraticRegion, Int_t const quadraticAlgo)
{
// Do running sum of coef/func pairs, calculate lastCoef.
Double_t central = funcList[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

   Double_t central = funcList[0];
                      ^

Double_t value = central;

for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double coefVal = coefList[iCoef];
                       ^


for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
double funcUp = funcList[(2 * iCoef) + 1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double funcUp = funcList[(2 * iCoef) + 1];
                      ^

for (std::size_t iCoef = 0; iCoef < nCoeffs; ++iCoef) {
double coefVal = coefList[iCoef];
double funcUp = funcList[(2 * iCoef) + 1];
double funcDn = funcList[(2 * iCoef) + 2];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

      double funcDn = funcList[(2 * iCoef) + 2];
                      ^

@runtingt
Copy link
Contributor Author

@vgvassilev I fixed up most of the suggestions, with the exception of these do not use pointer arithmetic warnings. I wanted to use a RooArgList instead of these double const* arr arrays, but when creating the NLL object with the codegen backend I get

input_line_152:53:75: error: reference to type 'const RooArgList' could not bind to an lvalue of type 'double[1]'
        const double t15 = RooFit::Detail::MathFuncs::verticalInterpolate(t9, t11, 0.000000, 0.000000, 0);
                                                                          ^~

Am I missing something obvious?

@vgvassilev
Copy link

@vgvassilev I fixed up most of the suggestions, with the exception of these do not use pointer arithmetic warnings.

Generally a good idea but sometimes it's just too awkward. We have an option to add the // NOLINT(...) clause to suppress them or just suppress them generally in the .clang-tidy file if this is a common development pattern in combine...

I wanted to use a RooArgList instead of these double const* arr arrays, but when creating the NLL object with the codegen backend I get

input_line_152:53:75: error: reference to type 'const RooArgList' could not bind to an lvalue of type 'double[1]'
        const double t15 = RooFit::Detail::MathFuncs::verticalInterpolate(t9, t11, 0.000000, 0.000000, 0);
                                                                          ^~

Am I missing something obvious?

Not obvious to me but may be obvious to @guitargeek...

@anigamova
Copy link
Collaborator

Hi @runtingt, could you explain a bit why and where were you trying to introduce RooArgLists exactly? Do you mean the funcList and coefList or something else?

@runtingt
Copy link
Contributor Author

Hi @runtingt, could you explain a bit why and where were you trying to introduce RooArgLists exactly? Do you mean the funcList and coefList or something else?

Hi @anigamova, exactly the funcList and coefList (and funcIntList which is functionally the same). These are already RooArgLists (see e.g. here), so it's more a case of trying to use them as part of the AD call.

In order to avoid the above input_line_152:53:75: error: reference to type 'const RooArgList' could not bind to an lvalue of type 'double[1]' (which I believe is from clad), I had to introduce another overload with the more primitive double const* char arrays, done here.

This upsets clang-tidy: warning: do not use pointer arithmetic, but I'm not sure there's a way to avoid both. Does that help at all?

@vgvassilev
Copy link

In order to avoid the above input_line_152:53:75: error: reference to type 'const RooArgList' could not bind to an lvalue of type 'double[1]' (which I believe is from clad)

Can you open an issue against the clad repository?

cc: @PetroZarytskyi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants