Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crash on trivial program #1186

Closed
samuelpmish opened this issue May 12, 2023 · 2 comments · Fixed by #1188
Closed

crash on trivial program #1186

samuelpmish opened this issue May 12, 2023 · 2 comments · Fixed by #1188

Comments

@samuelpmish
Copy link
Collaborator

see: https://fwd.gymni.ch/qW2CKI

duplicated here for completeness:

#include <stdio.h>

int enzyme_dup;
int enzyme_out;
int enzyme_const;

template < typename return_type, typename ... T >
extern return_type __enzyme_fwddiff(void*, T ... );

double square(double x) { return x * x; }

template < typename function, typename T > 
auto jvp(function f, T arg, T darg) {
  using output_type = decltype(f(arg));
  return __enzyme_fwddiff<output_type>((void*)f, enzyme_dup, arg, darg); 
}

int main() {

    // calling fwddiff directly seems to work
    auto output1 = __enzyme_fwddiff<double>((void*)square, enzyme_dup, 1.0, 1.0);
    printf("%f\n", output1);

    // calling fwddiff with the same args in a function template crashes
    auto output2 = jvp(square, 1.0, 1.0);
    printf("%f\n", output2);

}
@wsmoses
Copy link
Member

wsmoses commented May 12, 2023

Added a PR to make a reasonable error message.

Regardless the issue here is that the function pointer isn't a constant by differentiation time. Increasing the optimization level remedies. Adding static can also help fix (perhaps at a lower opt level): You could also pass the function as a template param perhaps?

wmoses@beast:~/git/Enzyme/enzyme/build12 (enofn) $ /home/wmoses/llvms/llvm12/buildD/./bin/clang -g -O0 /home/wmoses/git/Enzyme/enzyme/test/Integration/ForwardMode/nofn.cpp -S -emit-llvm -o -   -Xclang -load -Xclang /home/wmoses/git/Enzyme/enzyme/build12/Enzyme/ClangEnzyme-12.so -o /dev/null
/home/wmoses/git/Enzyme/enzyme/test/Integration/ForwardMode/nofn.cpp:19:10: error: Enzyme: failed to find fn to differentiate  %call = call double @_Z16__enzyme_fwddiffIdJiddEET_PvDpT0_(i8* %1, i32 %2, double %3, double %4), !dbg !616 - found -   %1 = bitcast double (double)* %0 to i8*, !dbg !612
  return __enzyme_fwddiff<output_type>((void*)f, enzyme_dup, arg, darg); // expected-error {{Enzyme: failed to find fn to differentiate}}
         ^
1 error generated.
wmoses@beast:~/git/Enzyme/enzyme/build12 (enofn) $ /home/wmoses/llvms/llvm12/buildD/./bin/clang -g -O0 /home/wmoses/git/Enzyme/enzyme/test/Integration/ForwardMode/nofn.cpp -S -emit-llvm -o -   -Xclang -load -Xclang /home/wmoses/git/Enzyme/enzyme/build12/Enzyme/ClangEnzyme-12.so -o /dev/null -O1
/home/wmoses/git/Enzyme/enzyme/test/Integration/ForwardMode/nofn.cpp:19:10: error: Enzyme: failed to find fn to differentiate  %call = call double @_Z16__enzyme_fwddiffIdJiddEET_PvDpT0_(i8* %0, i32 %1, double %arg, double %darg), !dbg !618 - found -   %0 = bitcast double (double)* %f to i8*, !dbg !612
  return __enzyme_fwddiff<output_type>((void*)f, enzyme_dup, arg, darg); // expected-error {{Enzyme: failed to find fn to differentiate}}
         ^
1 error generated.
wmoses@beast:~/git/Enzyme/enzyme/build12 (enofn) $ /home/wmoses/llvms/llvm12/buildD/./bin/clang -g -O0 /home/wmoses/git/Enzyme/enzyme/test/Integration/ForwardMode/nofn.cpp -S -emit-llvm -o -   -Xclang -load -Xclang /home/wmoses/git/Enzyme/enzyme/build12/Enzyme/ClangEnzyme-12.so -o /dev/null -O2

@samuelpmish
Copy link
Collaborator Author

for reference, @wsmoses suggestion of moving the function to a template argument seems like a reasonable workaround:

#include <stdio.h>

int enzyme_dup;
int enzyme_out;
int enzyme_const;

template < typename return_type, typename ... T >
extern return_type __enzyme_fwddiff(void*, T ... );

double square(double x) { return x * x; }

template < auto function, typename T > 
auto jvp(T arg, T darg) {
  using output_type = decltype(function(arg));
  return __enzyme_fwddiff<output_type>((void*)function, enzyme_dup, arg, darg); 
}

int main() {

    // calling fwddiff directly seems to work
    auto output1 = __enzyme_fwddiff<double>((void*)square, enzyme_dup, 1.0, 1.0);
    printf("%f\n", output1);

    // calling fwddiff with the function as a template argument doesn't crash any more
    auto output2 = jvp<square>(1.0, 1.0);
    printf("%f\n", output2);

}

note: C++17 or later is required to use the auto template parameter

https://fwd.gymni.ch/q3DHL9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants