clad icon indicating copy to clipboard operation
clad copied to clipboard

Regression with Clad `master` in case of num-diff fallback in specific conditions

Open guitargeek opened this issue 1 year ago • 0 comments

Some of the RooFit tests are still failing with Clad master, because of code that hits very specific conditions.

To reproduce the underlying problem, first create a library with any function:

// clang++ -fPIC mylib.cxx -c -o mylib.o && ar r libmylib.a mylib.o

double foo(double x, double y, double z)
{
   return x * y * z;
}

Then use that library in a function the is differentiated:

// Compile with clang++ -O2 -std=c++20 -fplugin=/usr/lib/clad.so repro_regression.cxx -o repro_regression -lmylib -L.

#include "clad/Differentiator/Differentiator.h"

#include <iostream>
#include <vector>

double foo(double x, double y, double z);

double wrapper(double *params)
{
   if (true) {
      double constant = 11.;
      return foo(params[0], constant, 1.);
   }

   return 0.0;
}

int main()
{
   std::vector<double> params{4};

   std::cout << "Value" << std::endl;
   const double nllVal = wrapper(params.data());
   std::cout << nllVal << std::endl;
   std::cout << std::endl;

   auto grad = clad::gradient(wrapper, "params");

   std::vector<double> gradResult(1);
   grad.execute(params.data(), gradResult.data());

   std::cout << "Clad diff:" << std::endl;
   std::cout << gradResult[0] << std::endl;
   std::cout << std::endl;

   auto numDiff = [&](int i) {
      const double eps = 1e-6;
      std::vector<double> p{params};
      p[i] = params[i] - eps;
      double nllValDown = wrapper(p.data());
      p[i] = params[i] + eps;
      double nllValUp = wrapper(p.data());
      return (nllValUp - nllValDown) / (2 * eps);
   };

   std::cout << "Num diff:" << std::endl;
   std::cout << numDiff(0) << std::endl;
}

Many conditions need to be met to get this Clad error:

  • You need to compile with -O2
  • You need to call a function in a library such that Clad falls back to num. diff.
  • The code needs to be in a branch, like this if (true) in the reproducer
  • One of the function variables must be a named variable (i.e., doing foo(params[0], 11., 1.) would not hit the bug)

The output will be:

Value
44

Clad diff:
0

Num diff:
11

My compiler setup:

clang version 16.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /bin

guitargeek avatar Dec 13 '23 00:12 guitargeek