Comments (9)
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.
Adding a MFE which used to work in the original PR for the C++ interface https://fwd.gymni.ch/nsKPWF
from enzyme.
@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.
@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.
@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.
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.
@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.
Seemingly resolved.
from enzyme.
Thank you! Sorry for being very inconsistent with GH activity
from enzyme.
Related Issues (20)
- Bug in Enzyme gsl branch HOT 6
- compilation slowdown associated with PreserveNVVMNewPM HOT 1
- Is this N/3 correct? HOT 10
- incorrect derivative of function that returns struct HOT 2
- `std::vector.push_back()` causes segementation fault in Enzyme HOT 2
- EnzymeCreateForwardDiff missing from CApi.h HOT 1
- Clarify usage through linking HOT 10
- Failing unittest Enzyme/ReverseMode/gsl_sf_legendre_array_e.ll
- Enzyme C++ sugar for vector input/outputs HOT 1
- Batching for Vector Intrinsics
- Syntax for custom forward rule in C? HOT 4
- How to use enzyme in my makefile? HOT 2
- Compiling with -O{1,2,3} breaks custom rule that works with -O0 HOT 2
- incorrect gradient for if statement HOT 2
- Failure with new c++ sugar
- Enzyme TA expectations/issues HOT 4
- C++ interface TODO list HOT 1
- No pass found for various GSL FFT and Statistics methods
- Enzyme derivatives attempting to free stack allocations HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from enzyme.