Enzyme icon indicating copy to clipboard operation
Enzyme copied to clipboard

Invalid results in forward mode with the new C++ interface for a function returning a `std::array`

Open thelfer opened this issue 1 year ago • 2 comments

The issue is probably due to my own inexperience.

The following snippet returns the value of the function rather than its derivative:

    const double x = 1.0;
    const double dx = 1.0;
    const auto c = [](const double& x) {
      return std::array{std::cos(x), 2*std::sin(x)};
    };
    const auto dfdx = ::enzyme::get<0>(enzyme::autodiff<::enzyme::Forward>(
        +c, ::enzyme::Duplicated<const double&>{x, dx}));
    std::cout << "dfdx:\n" << dfdx[0] << ", expected:  " << -std::sin(1) << "\n"
              << dfdx[1] << ", expected: " << 2 * std::cos(1) << std::endl;

In contrast, the old interface behaves correctly

   const auto dfdx_2 =
       __enzyme_fwddiff<std::array<double, 2>>(+c, enzyme_dup, &x, &dx);
   std::cout << "dfdx_2:\n" << dfdx_2[0] << ", expected:  " << -std::sin(1) << "\n"
             << dfdx_2[1] << ", expected: " << 2 * std::cos(1) << std::endl;

Any help would be appreciated ! @samuelpmish ?

P.S. enzyme::autodiff<::enzyme::Forward> works fine for scalar valuated functions.

thelfer avatar Sep 26 '24 07:09 thelfer

looking at the generated assembly, it shows that enzyme::autodiff is returning the value of the function in your example (not the derivative w.r.t. x):

https://fwd.gymni.ch/0Z2DlV

I'm not sure what the cause is, but we can look into it. I forget: is enzyme::forward(f, args) intended to return both {f, df} or just df?

samuelpmish avatar Sep 26 '24 15:09 samuelpmish

@samuelpmish Thanks for watching.

In the scalar case, only df is returned, so I would expect the same in this case. This is also the case when using the raw __enzyme_fwddiff.

thelfer avatar Sep 26 '24 15:09 thelfer