Giter Club home page Giter Club logo

Comments (9)

wsmoses avatar wsmoses commented on July 23, 2024

Yeah it is known that references aren't handled properly in the new interface, help definitely welcome!

And yeah tentaitlvely c++17, though obviously earlier support would be nice if possible

from enzyme.

jandrej avatar jandrej commented on July 23, 2024

Adding a MFE which used to work in the original PR for the C++ interface https://fwd.gymni.ch/nsKPWF

from enzyme.

GregTheMadMonk avatar GregTheMadMonk commented on July 23, 2024

@jandrej with #1914 your code compiles with the following minor changes:

62,64c62,63
<    return std::tuple<enzyme::Duplicated<decltype(std::get<Is>(args))>...>{
<       { std::get<Is>(args), std::get<Is>(shadow_args) }...
<    };
---
>    return std::tuple_cat(std::make_tuple(
>                             enzyme::Duplicated<std::remove_cv_t<std::remove_reference_t<decltype(std::get<Is>(args))>>*> {&std::get<Is>(args), &std::get<Is>(shadow_args)})...);
87c86
<                 enzyme::autodiff<enzyme::Forward>
---
>                 enzyme::autodiff<enzyme::Forward, enzyme::DuplicatedNoNeed<kf_return_t>>
106,110c105
<     std::get<0>(kernel_args) = 3;
<     std::get<0>(kernel_shadow_args) = 1;
<
<     const auto res = fwddiff_apply_enzyme(func, kernel_args, kernel_shadow_args);
<     std::cout << res << " == 6\n";
---
>     fwddiff_apply_enzyme(func, kernel_args, kernel_shadow_args);

(I've replaced std::make_tuple(std::tuple_cat(... with a std::tuple constructor to make it compile with C++23, which I use. Note that the enzyme::Duplicated argument has also changed from the pointer to a reference. Waiting for a response on my PR to know if I understood Duplicated/DuplicatedNoNeed right).

It still doesn't work as intended (prints 0 == 6), since, as I've discovered, the C++ interface also doesn't process function pointers correctly. For example, this code

#include <enzyme/enzyme>
#include <iostream>

double f(const double& x) { return x * x; }

int main() {
    double x = 3, dx = 0;
    enzyme::autodiff<enzyme::Reverse>(
        f, enzyme::Duplicated<const double&>{ x, dx }
    );
    std::cout << x << ' ' << dx << '\n';
    return 0;
}

will compile and work meanwhile this:

#include <enzyme/enzyme>
#include <iostream>

double f(const double& x) { return x * x; }

int main() {
    double x = 3, dx = 0;
    enzyme::autodiff<enzyme::Reverse>(
        &f, enzyme::Duplicated<const double&>{ x, dx }
    );
    std::cout << x << ' ' << dx << '\n';
    return 0;
}

will not:

error: Enzyme: No create nofree of unknown value
ptr %2
 at context:   %4 = tail call noundef double %3(ptr noundef nonnull align 8 dereferenceable(8) %0) #7
1 error generated.
make[2]: *** [CMakeFiles/test.dir/build.make:76: CMakeFiles/test.dir/main.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:910: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

(nevermind the line numbers, I'm testing everything in a single main.cc with a few #if 0 ... #endif's)

from enzyme.

wsmoses avatar wsmoses commented on July 23, 2024

@GregTheMadMonk the issue is that we need to ensure that all the reference passes do not end up creating a copy and thus the autodiff/fwddiff call gets the pointer to the actual reference provided.

Re function pointers, they are supported, but when passed directly. (like the top)

from enzyme.

GregTheMadMonk avatar GregTheMadMonk commented on July 23, 2024

@wsmoses Sorry, I'm not sure I quite follow what you're saying... Do you mean that we need to ensure that the pointer __enzyme_autodiff/__enzyme_fwddiff end up getting point to the same variables the user has provided when they have called the code? In that case there indeed will be no copying of data, only of references and pointer to it (but I'll re-check it).

Then there is also the issue that I've written about in the PR comments - but I see you've already read and replied to it :)

And I also realize (now) why function pointers can't really be processed (since a function pointer could point to any function really and there is no guarantee it was processed by Enzyme). __enzyme_autodiff can process some though (e.g. when passing a compile-time known function pointer via &f or +lambda). Should this be preserved, or outright prohibited (ideally via a static_assert with a message explaining why function pointers are not to be used in this context and what could be used instead)?

It seems that the best self-critique arrives after the code has been submitted...

It's getting quite late, I won't be replying for a while

from enzyme.

wsmoses avatar wsmoses commented on July 23, 2024

So we can find out what's happening by looking at the generated LLVM. If there's a copy somewhere we'll see a different allocation passed to the underlying __enzyme_autodiff (which is my guess why it could get a different answer than expected).

It would be nice to do a check at the outermost c++ api level (though we have some internal shenanigans to handle a slightly wider scope).

from enzyme.

jandrej avatar jandrej commented on July 23, 2024

@GregTheMadMonk did you check the output values? I only get zeros from the fwddiff in your branch.
edit:
Just understood your comment now. I hope you find the problem, I'm happy to test.

from enzyme.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.