clad icon indicating copy to clipboard operation
clad copied to clipboard

Error when trying to differentiate a function which takes `RooArgList`(s)

Open runtingt opened this issue 11 months ago • 1 comments

Hi, I've run into an issue when trying to differentiate a function which takes a RooArgList as an argument when implementing AD for a custom class in the CMS Combine tool (see https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/pull/1060). Specifically, we see

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);
                                                                          ^~

I've put together the following reproducer:

// Some function that takes in RooArgList(s)
Double_t do_linear_comb(RooArgList l1, RooArgList l2) {
  Double_t result = 0.0;
  for (int i = 0; i < l1.getSize(); i++) {
    Double_t coefVal = static_cast<RooAbsReal&>(l1[i]).getVal();
    Double_t funcVal = static_cast<RooAbsReal&>(l2[i]).getVal();
    result += coefVal * funcVal;
  }
  return result;
}

// MWE class to be extended with AD
class LinearCombPdf : public RooAbsPdf {
public:
  LinearCombPdf(const char* name, const char* title, const RooArgList& coefficients, const RooArgList& functions) :
    RooAbsPdf(name, title), _coefficients("coefficients", "List of coefficients", this), _functions("functions", "List of functions", this)
  {
    for (int i = 0; i < coefficients.size(); i++) {
      _coefficients.add(*coefficients.at(i));
    }
    
    for (int i = 0; i < functions.size(); i++) {
      _functions.add(*functions.at(i));
    }
  }
  LinearCombPdf(const LinearCombPdf& other, const char* name = 0) :
    RooAbsPdf(other, name), _coefficients("coefficients", this, other._coefficients), _functions("functions", this, other._functions) {}
  virtual TObject* clone(const char* newname) const override { return new LinearCombPdf(*this, newname);}
  const RooArgList& funcList() const { return _functions ; }
  const RooArgList& coefList() const { return _coefficients ; }
  void translate(RooFit::Detail::CodeSquashContext &ctx) const override
  {
    ctx.addResult(this, ctx.buildCall("do_linear_comb", this->coefList(), this->funcList()));
  }

protected:
  Double_t evaluate() const override { return do_linear_comb(_coefficients, _functions); }
  ClassDefOverride(LinearCombPdf, 1)

private:
  RooListProxy _coefficients;
  RooListProxy _functions;

};

void test() {
  // Setup
  RooRealVar x("x", "x", -10, 10);
  RooRealVar c0("c0", "c0", 1.);
  RooRealVar c1("c1", "c1", 2.);
  RooFormulaVar f0("f0", "f0", "1", RooArgList(x));
  RooFormulaVar f1("f1", "f1", "x", RooArgList(x));

  RooArgList coefficients;
  coefficients.add(c0);
  coefficients.add(c1);
  RooArgList functions;
  functions.add(f0);
  functions.add(f1);
  
  // Create NLL
  LinearCombPdf pdf("pdf", "pdf", coefficients, functions);
  auto data = pdf.generate(x);
  pdf.createNLL(*data, RooFit::EvalBackend("codegen"));
}

test();

which produces the same error:

$ root
root [0] .L repro.C 
[#1] INFO:Fitting -- RooAbsPdf::fitTo(pdf_over_pdf_Int[x]) fixing normalization set for coefficient determination to observables in data
[#1] INFO:Fitting -- using CPU computation library compiled with -mavx2
input_line_18:4:16: error: no matching function for call to 'TFormula____id10159970873491820195'
double t4[] = {TFormula____id10159970873491820195(nullptr),TFormula____id2091452422826374425(t6)};
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
input_line_11:2:10: note: candidate function not viable: requires 0 arguments, but 1 was provided
Double_t TFormula____id10159970873491820195(){ return 1 ; }
         ^
input_line_18:6:9: error: no matching function for call to 'do_linear_comb'
 return do_linear_comb(t3, t4);
        ^~~~~~~~~~~~~~
/home/tr1123/Documents/CladMWE/repro.C:2:10: note: candidate function not viable: no known conversion from 'double[2]' to 'RooArgList' for 1st argument
Double_t do_linear_comb(RooArgList l1, RooArgList l2) {
         ^              ~~~~~~~~~~~~~
[#0] ERROR:InputArguments -- Function roo_func_wrapper_0 could not be compiled. See above for details.
Error in <TRint::HandleTermInput()>: std::runtime_error caught: Function roo_func_wrapper_0 could not be compiled. See above for details.

Specifically (and I'm not sure how useful this is), this was run using the root.x86_64 6.34.06-1.fc42 build for Fedora, but we also see this behaviour with ROOT master in the referenced PR.

runtingt avatar Apr 23 '25 22:04 runtingt

@guitargeek, can you give us a hand with this issue?

vgvassilev avatar May 25 '25 08:05 vgvassilev