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

Cannot deduce adding type of: i32 when function is defined in seperate include file #1574

Closed
ipcamit opened this issue Dec 8, 2023 · 7 comments

Comments

@ipcamit
Copy link

ipcamit commented Dec 8, 2023

Hi,
I get the following error:

Cannot deduce adding type
UNREACHABLE executed at /opt/enzyme/enzyme/Enzyme/DiffeGradientUtils.cpp:411!

when I define my function in a separate file, maths.cpp/maths.hpp. If I include the function in same file, Descriptors.cpp/hpp, it compiles fine. I am copy pasting the files below, as well as a tar folder to reproduce the error.

Full error:

[1/1] Linking CXX shared library libdescriptor.so
FAILED: libdescriptor.so 
: && /opt/llvm_13/clang_13_prebuilt/bin/clang++ -fPIC -fuse-ld=lld -flto -Xclang -new-struct-path-tbaa -O3 -DNDEBUG  -Xlinker --lto-legacy-pass-manager -Xlinker -mllvm=-load=/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so -shared -Wl,-soname,libdescriptor.so -o libdescriptor.so CMakeFiles/descriptor.dir/Descriptors.cpp.o CMakeFiles/descriptor.dir/maths.cpp.o   && :
freeing without malloc   %30 = phi double* [ null, %19 ], [ %24, %21 ]
oldFunc: ; Function Attrs: mustprogress uwtable willreturn
define void @preprocess__ZN2Xi7computeEiiPiS0_iPdS1_(%class.Xi* nocapture nonnull readonly align 8 dereferenceable(88) %0, i32 %1, i32 %2, i32* nocapture readnone %3, i32* nocapture readnone %4, i32 %5, double* nocapture readnone %6, double* nocapture readnone %7) unnamed_addr #15 align 2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
  %9 = tail call noalias nonnull i8* @_Znwm(i64 800) #18
  %10 = bitcast i8* %9 to double*
  tail call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(800) %9, i8 0, i64 800, i1 false) #19
  %11 = getelementptr inbounds %class.Xi, %class.Xi* %0, i64 0, i32 1
  %12 = load i32, i32* %11, align 4, !tbaa !39
  %13 = add nsw i32 %12, 1
  %14 = mul nsw i32 %13, %5
  %15 = mul nsw i32 %14, %13
  %16 = sext i32 %15 to i64
  %17 = icmp slt i32 %15, 0
  br i1 %17, label %18, label %19

18:                                               ; preds = %8
  call void @_ZSt20__throw_length_errorPKc(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.2, i64 0, i64 0)) #20
  unreachable

19:                                               ; preds = %8
  %20 = icmp eq i32 %15, 0
  br i1 %20, label %28, label %21

21:                                               ; preds = %19
  %22 = shl nuw nsw i64 %16, 3
  %23 = call noalias nonnull i8* @_Znwm(i64 %22) #18
  %24 = bitcast i8* %23 to double*
  call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %23, i8 0, i64 %22, i1 false) #19
  %25 = getelementptr i8, i8* %23, i64 %22
  %26 = load i32, i32* %11, align 4, !tbaa !39
  %27 = ptrtoint i8* %25 to i64
  br label %28

28:                                               ; preds = %21, %19
  %29 = phi i32 [ %12, %19 ], [ %26, %21 ]
  %30 = phi double* [ null, %19 ], [ %24, %21 ]
  %31 = phi i64 [ 0, %19 ], [ %27, %21 ]
  %32 = getelementptr inbounds %class.Xi, %class.Xi* %0, i64 0, i32 2
  %33 = load double, double* %32, align 8, !tbaa !43
  %34 = ptrtoint double* %30 to i64
  %35 = sub i64 %31, %34
  %36 = lshr exact i64 %35, 3
  %37 = trunc i64 %36 to i32
  call void @_Z12bessel_basisidiPdiS_(i32 %29, double %33, i32 %5, double* nonnull %10, i32 %37, double* %30) #19
  %38 = icmp eq double* %30, null
  br i1 %38, label %41, label %39

39:                                               ; preds = %28
  %40 = bitcast double* %30 to i8*
  tail call void @_ZdlPv(i8* nonnull %40) #21
  br label %41

41:                                               ; preds = %39, %28
  tail call void @_ZdlPv(i8* nonnull %9) #21
  ret void
}

Cannot deduce adding type of: i32 %5
<analysis>
i32 0: {[-1]:Anything}, intvals: {0,}
i32 1: {[-1]:Integer}, intvals: {1,}
i64 0: {[-1]:Anything}, intvals: {0,}
[49 x i8] c"cannot create std::vector larger than max_size()\00": {[-1]:Anything}, intvals: {}
i8 114: {[-1]:Integer}, intvals: {114,}
  %25 = getelementptr i8, i8* %23, i64 %22: {[-1]:Pointer}, intvals: {}
i8 115: {[-1]:Integer}, intvals: {115,}
i8 99: {[-1]:Integer}, intvals: {99,}
double* null: {[-1]:Pointer, [-1,-1]:Anything}, intvals: {0,}
i8 0: {[-1]:Integer}, intvals: {0,}
i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.2, i64 0, i64 0): {[-1]:Pointer, [-1,-1]:Anything}, intvals: {}
@.str.2 = private unnamed_addr constant [49 x i8] c"cannot create std::vector larger than max_size()\00", align 1: {[-1]:Pointer, [-1,-1]:Anything}, intvals: {}
i64 3: {[-1]:Integer}, intvals: {3,}
  call void @_Z12bessel_basisidiPdiS_(i32 %29, double %33, i32 %5, double* nonnull %10, i32 %37, double* %30) #19: {}, intvals: {}
  %30 = phi double* [ null, %19 ], [ %24, %21 ]: {[-1]:Pointer}, intvals: {0,}
  %29 = phi i32 [ %12, %19 ], [ %26, %21 ]: {[-1]:Integer}, intvals: {}
  %31 = phi i64 [ 0, %19 ], [ %27, %21 ]: {[-1]:Pointer}, intvals: {0,}
  %22 = shl nuw nsw i64 %16, 3: {[-1]:Integer}, intvals: {}
  %13 = add nsw i32 %12, 1: {[-1]:Integer}, intvals: {}
i8 105: {[-1]:Integer}, intvals: {105,}
i8 32: {[-1]:Integer}, intvals: {32,}
i8 97: {[-1]:Integer}, intvals: {97,}
i8 109: {[-1]:Integer}, intvals: {109,}
i8 120: {[-1]:Integer}, intvals: {120,}
i8 95: {[-1]:Integer}, intvals: {95,}
i8 122: {[-1]:Integer}, intvals: {122,}
i8 40: {[-1]:Integer}, intvals: {40,}
i8 41: {[-1]:Integer}, intvals: {41,}
i8 58: {[-1]:Integer}, intvals: {58,}
i8 118: {[-1]:Integer}, intvals: {118,}
i8 108: {[-1]:Integer}, intvals: {108,}
i8 103: {[-1]:Integer}, intvals: {103,}
i8 104: {[-1]:Integer}, intvals: {104,}
i8 110: {[-1]:Integer}, intvals: {110,}
i8 100: {[-1]:Integer}, intvals: {100,}
  %16 = sext i32 %15 to i64: {[-1]:Integer}, intvals: {}
  %26 = load i32, i32* %11, align 4, !tbaa !16: {[-1]:Integer}, intvals: {}
  %23 = call noalias nonnull i8* @_Znwm(i64 %22) #18: {[-1]:Pointer}, intvals: {}
  %15 = mul nsw i32 %14, %13: {[-1]:Integer}, intvals: {}
  %12 = load i32, i32* %11, align 4, !tbaa !16: {[-1]:Integer}, intvals: {}
  %24 = bitcast i8* %23 to double*: {[-1]:Pointer}, intvals: {}
%class.Xi* %0: {[-1]:Pointer, [-1,52]:Integer, [-1,53]:Integer, [-1,54]:Integer, [-1,55]:Integer, [-1,56]:Float@double}, intvals: {}
i32 %1: {}, intvals: {}
i32 %2: {}, intvals: {}
i32* %3: {}, intvals: {}
i32* %4: {}, intvals: {}
i32 %5: {[-1]:Integer}, intvals: {}
double* %6: {}, intvals: {}
double* %7: {}, intvals: {}
  %27 = ptrtoint i8* %25 to i64: {[-1]:Pointer}, intvals: {}
  %40 = bitcast double* %30 to i8*: {[-1]:Pointer}, intvals: {0,}
  %32 = getelementptr inbounds %class.Xi, %class.Xi* %0, i64 0, i32 2: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
  %35 = sub i64 %31, %34: {[-1]:Integer}, intvals: {0,}
  %36 = lshr exact i64 %35, 3: {[-1]:Integer}, intvals: {0,}
  %38 = icmp eq double* %30, null: {[-1]:Integer}, intvals: {}
  %33 = load double, double* %32, align 8, !tbaa !23: {[-1]:Float@double}, intvals: {}
  %10 = bitcast i8* %9 to double*: {[-1]:Pointer}, intvals: {}
i8 116: {[-1]:Integer}, intvals: {116,}
i8 111: {[-1]:Integer}, intvals: {111,}
  %34 = ptrtoint double* %30 to i64: {[-1]:Pointer}, intvals: {0,}
  %14 = mul nsw i32 %13, %5: {[-1]:Integer}, intvals: {}
  %9 = tail call noalias nonnull i8* @_Znwm(i64 800) #18: {[-1]:Pointer}, intvals: {}
i8 101: {[-1]:Integer}, intvals: {101,}
  %37 = trunc i64 %36 to i32: {[-1]:Integer}, intvals: {0,}
  %17 = icmp slt i32 %15, 0: {[-1]:Integer}, intvals: {}
  %20 = icmp eq i32 %15, 0: {[-1]:Integer}, intvals: {}
  %11 = getelementptr inbounds %class.Xi, %class.Xi* %0, i64 0, i32 1: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}, intvals: {}
</analysis>

Cannot deduce adding type
UNREACHABLE executed at /opt/enzyme/enzyme/Enzyme/DiffeGradientUtils.cpp:411!
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/llvm_13/clang_13_prebuilt/bin/ld.lld -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -shared -o libdescriptor.so /lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/opt/llvm_13/clang_13_prebuilt/bin/../lib -L/lib -L/usr/lib -plugin-opt=mcpu=x86-64 -plugin-opt=O3 --lto-legacy-pass-manager -mllvm=-load=/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so -soname libdescriptor.so CMakeFiles/descriptor.dir/Descriptors.cpp.o CMakeFiles/descriptor.dir/maths.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /lib/x86_64-linux-gnu/crtn.o
1.	Running pass 'Enzyme Pass' on module 'ld-temp.o'.
 #0 0x0000000002576d63 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x2576d63)
 #1 0x0000000002574d4e llvm::sys::RunSignalHandlers() (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x2574d4e)
 #2 0x000000000257734f SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fbc0be30420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007fbc0b8c300b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007fbc0b8a2859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00000000024eaa61 (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x24eaa61)
 #7 0x00007fbc0b30982d DiffeGradientUtils::addToDiffe(llvm::Value*, llvm::Value*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&, llvm::Type*, llvm::ArrayRef<llvm::Value*>, llvm::Value*) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0x8d782d)
 #8 0x00007fbc0b217271 AdjointGenerator<AugmentedReturn const*>::addToDiffe(llvm::Value*, llvm::Value*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&, llvm::Type*, llvm::Value*) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0x7e5271)
 #9 0x00007fbc0b479909 AdjointGenerator<AugmentedReturn const*>::recursivelyHandleSubfunction(llvm::CallInst&, llvm::Function*, std::vector<bool, std::allocator<bool> > const&, bool, DIFFE_TYPE, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xa47909)
#10 0x00007fbc0b46d60c AdjointGenerator<AugmentedReturn const*>::visitCallInst(llvm::CallInst&) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xa3b60c)
#11 0x00007fbc0b46ab2b llvm::InstVisitor<AdjointGenerator<AugmentedReturn const*>, void>::delegateCallInst(llvm::CallInst&) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xa38b2b)
#12 0x00007fbc0b455dad llvm::InstVisitor<AdjointGenerator<AugmentedReturn const*>, void>::visitCall(llvm::CallInst&) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xa23dad)
#13 0x00007fbc0b45526a llvm::InstVisitor<AdjointGenerator<AugmentedReturn const*>, void>::visit(llvm::Instruction&) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xa2326a)
#14 0x00007fbc0b3f67ed llvm::InstVisitor<AdjointGenerator<AugmentedReturn const*>, void>::visit(llvm::Instruction*) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0x9c47ed)
#15 0x00007fbc0b3df41f EnzymeLogic::CreatePrimalAndGradient(RequestContext, ReverseCacheKey const&&, TypeAnalysis&, AugmentedReturn const*, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0x9ad41f)
#16 0x00007fbc0b534847 GradientUtils::GetOrCreateShadowFunction(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Function*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb02847)
#17 0x00007fbc0b5323d8 GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb003d8)
#18 0x00007fbc0b53248c GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb0048c)
#19 0x00007fbc0b53200a GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb0000a)
#20 0x00007fbc0b532185 GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb00185)
#21 0x00007fbc0b532e4c GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb00e4c)
#22 0x00007fbc0b53248c GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb0048c)
#23 0x00007fbc0b53248c GradientUtils::GetOrCreateShadowConstant(RequestContext, EnzymeLogic&, llvm::TargetLibraryInfo&, TypeAnalysis&, llvm::Constant*, DerivativeMode, unsigned int, bool) (/opt/enzyme/enzyme/build/Enzyme/LLDEnzyme-13.so+0xb0048c)
#24 0x00007fbc0b36490d (anonymous namespace)::EnzymeBase::lowerEnzymeCalls(llvm::Function&, std::set<llvm::Function*, std::less<llvm::Function*>, std::allocator<llvm::Function*> >&) Enzyme.cpp:0:0
#25 0x00007fbc0b35f744 (anonymous namespace)::EnzymeBase::run(llvm::Module&) Enzyme.cpp:0:0
#26 0x00007fbc0b35ee21 (anonymous namespace)::EnzymeOldPM::runOnModule(llvm::Module&) Enzyme.cpp:0:0
#27 0x000000000507a204 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x507a204)
#28 0x0000000003c48845 llvm::lto::opt(llvm::lto::Config const&, llvm::TargetMachine*, unsigned int, llvm::Module&, bool, llvm::ModuleSummaryIndex*, llvm::ModuleSummaryIndex const*, std::vector<unsigned char, std::allocator<unsigned char> > const&) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x3c48845)
#29 0x0000000003c497ad llvm::lto::backend(llvm::lto::Config const&, std::function<std::unique_ptr<llvm::lto::NativeObjectStream, std::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)>, unsigned int, llvm::Module&, llvm::ModuleSummaryIndex&) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x3c497ad)
#30 0x0000000003c3cc09 llvm::lto::LTO::runRegularLTO(std::function<std::unique_ptr<llvm::lto::NativeObjectStream, std::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)>) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x3c3cc09)
#31 0x0000000003c3c492 llvm::lto::LTO::run(std::function<std::unique_ptr<llvm::lto::NativeObjectStream, std::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)>, std::function<std::function<std::unique_ptr<llvm::lto::NativeObjectStream, std::default_delete<llvm::lto::NativeObjectStream> > (unsigned int)> (unsigned int, llvm::StringRef)>) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x3c3c492)
#32 0x0000000002700d54 lld::elf::BitcodeCompiler::compile() (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x2700d54)
#33 0x000000000266e816 void lld::elf::LinkerDriver::compileBitcodeFiles<llvm::object::ELFType<(llvm::support::endianness)1, true> >() (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x266e816)
#34 0x000000000265a07d void lld::elf::LinkerDriver::link<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::opt::InputArgList&) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x265a07d)
#35 0x000000000264c818 lld::elf::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x264c818)
#36 0x0000000002649ffb lld::elf::link(llvm::ArrayRef<char const*>, bool, llvm::raw_ostream&, llvm::raw_ostream&) (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x2649ffb)
#37 0x00000000024d12c1 lldMain(int, char const**, llvm::raw_ostream&, llvm::raw_ostream&, bool) lld.cpp:0:0
#38 0x00000000024d0b94 main (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x24d0b94)
#39 0x00007fbc0b8a4083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#40 0x00000000024d071e _start (/opt/llvm_13/clang_13_prebuilt/bin/ld.lld+0x24d071e)
clang-13: error: unable to execute command: Aborted (core dumped)
clang-13: error: linker command failed due to signal (use -v to see invocation)
ninja: build stopped: subcommand failed.

LLVM version: 13.0.1
Enzyme Version: 0.0.94
dummy-descriptor-library.tar.gz


FILES


Headerfile: Descriptor.hpp ```C++ #include #include namespace Descriptor { enum AvailableDescriptor { KindXi //!< For selecting Xi descriptor };
class DescriptorKind;

void gradient(int n_atoms, int *species, int *neighbor_list, int *number_of_neighs,
              double *coordinates, double *d_coordinates, double *desc,
              double *dE_dzeta, DescriptorKind *descriptor_to_diff);

void compute(int n_atoms, int *species, int *neighbor_list, int *number_of_neighs,
             double *coordinates, double *desc,
             DescriptorKind *descriptor_kind);

}

class Descriptor::DescriptorKind {

public:
AvailableDescriptor descriptor_kind; //!< Kind of instantiated descriptor, will be used in creating clone for AD
std::string descriptor_param_file; //!< Full path to descriptor parameter file.
int width=-1; //!< Dimension of the descriptor

DescriptorKind() = default;

virtual void compute(int index,
                     int n_atoms,
                     int *species,
                     int *neighbor_lists,
                     int number_of_neighbors,
                     double *coordinates,
                     double *desc) = 0;

virtual ~DescriptorKind();

};

typedef double VectorOfSize3[3];

using namespace Descriptor;

class Xi final : public DescriptorKind{
public:
Xi() {}; //TODO delete the default constructor
Xi(std::string &filename){};//TODO complete this constructor

void compute(int index,
             int n_atoms,
             int *species,
             int *neighbor_lists,
             int number_of_neighbors,
             double *coordinates,
             double *desc) override;
int q;
double cutoff;

private:
std::vector radial_basis_array;
};

// UNCOMMENT THIS FOR SUCCESSFUL COMPILATION
//void bessel_basis(int n_max, double rc, int r_size, double *r,int r_basis_size, double *r_basis);


Source file: Descriptor.cpp
```C++
#include "Descriptors.hpp"
#include <vector>
#include <stdexcept>
#include <iostream>
// comment this out for successful compilation
#include "maths.hpp"

#define MAX_NEIGHBORS 100

int enzyme_dup, enzyme_out, enzyme_const;

template<typename T>
T __enzyme_virtualreverse(T);

// Rev mode diff
void __enzyme_autodiff(void (*)(int, int *, int *, int *, double *, double *, DescriptorKind *),
                       int, int /* n_atoms */,
                       int, int * /* Z */,
                       int, int * /* neighbor list */,
                       int, int * /* number_of_neigh_list */,
                       int, double * /* coordinates */, double * /* derivative w.r.t coordinates */,
                       int, double * /* zeta */, double * /* dzeta_dE */,
                       int, DescriptorKind * /* DescriptorKind to diff */, DescriptorKind * /* d_DescriptorKind */);
using namespace Descriptor;

void Descriptor::compute(int const n_atoms /* contributing */,
                         int *const species,
                         int *const neighbor_list,
                         int *const number_of_neighbors,
                         double *const coordinates,
                         double *const desc,
                         DescriptorKind *const desc_kind) {
    int *neighbor_ptr = neighbor_list;
    double *desc_ptr = desc;
    for (int i = 0; i < n_atoms; i++) {
        desc_kind->compute(i, n_atoms, species, neighbor_ptr, number_of_neighbors[i],
                           coordinates, desc_ptr);
        neighbor_ptr += number_of_neighbors[i];
        desc_ptr += desc_kind->width;
    }
}

void Descriptor::gradient(int n_atoms /* contributing */,
                          int *species,
                          int *neighbor_list,
                          int *number_of_neighbors,
                          double *coordinates,
                          double *d_coordinates,
                          double *desc,
                          double *d_desc, /* vector for vjp or jvp */
                          DescriptorKind *desc_kind) {
    switch (desc_kind->descriptor_kind) {
        case KindXi: {
            auto d_desc_kind = new Xi();
            *((void **) d_desc_kind) = __enzyme_virtualreverse(*((void **) d_desc_kind));
            __enzyme_autodiff(compute, /* fn to be differentiated */
                              enzyme_const, n_atoms, /* Do not diff. against integer params */
                              enzyme_const, species,
                              enzyme_const, neighbor_list,
                              enzyme_const, number_of_neighbors,
                              enzyme_dup, coordinates, d_coordinates,
                              enzyme_dup, desc, d_desc,
                              enzyme_dup, desc_kind, d_desc_kind);
            delete d_desc_kind;
            return;
        }
        default:
            std::cerr << "Descriptor kind not supported\n";
            throw std::invalid_argument("Descriptor kind not supported");
    }
}

DescriptorKind::~DescriptorKind() = default;

void Xi::compute(int index,
                 int n_atoms,
                 int *species,
                 int *neighbor_lists,
                 int number_of_neighbors,
                 double *coordinates,
                 double *desc) {
    auto r_ij = std::vector<double>(MAX_NEIGHBORS);
    auto gnl = std::vector<double>(number_of_neighbors * (q + 1) * (q + 1), 0.0);
    bessel_basis(q, cutoff, number_of_neighbors, r_ij.data(), gnl.size(), gnl.data());

}

// UNCOMMENT THIS FOR SUCCESSFUL COMPILATION
//void bessel_basis(int n_max, double rc, int r_size, double *r, int r_basis_size,double *r_basis) {
//    for (int i = 0; i < r_basis_size; i++) {
//        r_basis[i] = 0.0;
//    }
//}

Function files: maths.cpp and hpp

#include <cmath>
void bessel_basis(int n_max, double rc, int r_size, double *r,int r_basis_size, double *r_basis);
#include "maths.hpp"
void bessel_basis(int n_max, double rc, int r_size, double *r, int r_basis_size,double *r_basis) {
    for (int i = 0; i < r_basis_size; i++) {
        r_basis[i] = 0.0;
    }
}
cmake_minimum_required(VERSION 3.16)
project(libdescriptor)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_STANDARD 17)

#----------------
# Find enzyme at location ENZYME_LIB
string(REGEX MATCH "^[0-9]+" LLVM_MAJOR_VERSION ${CMAKE_CXX_COMPILER_VERSION})
message("LLVM major version used: ${LLVM_MAJOR_VERSION}")

if(NOT DEFINED ENZYME_LIB)
    message(WARNING "ENZYME_LIB variable not defined, switching to default: /usr/local/lib" )
    set(ENZYME_LIB "/usr/local/lib")
endif()
message("Searching for ENZYME at ${ENZYME_LIB}")
if(EXISTS "${ENZYME_LIB}/LLDEnzyme-${LLVM_MAJOR_VERSION}.so")
    message("Found LLDEnzyme plugin.")
endif()

# Set LLD, just in case... sometimes default LLD the name of LLD file is lld-12
if (NOT DEFINED LLD)
    set(LLD "lld")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=${LLD} -flto -Xclang -new-struct-path-tbaa")

file(GLOB SRC_FILES Descriptors.cpp maths.cpp)
#file(GLOB SRC_FILES Descriptors.cpp)

add_library(descriptor SHARED ${SRC_FILES})

# pass linking to lld, with enzyme plugin
if (${LLVM_MAJOR_VERSION} LESS_EQUAL 13)
    target_link_options(descriptor PRIVATE "LINKER:--lto-legacy-pass-manager")
    target_link_options(descriptor PRIVATE "LINKER:-mllvm=-load=${ENZYME_LIB}/LLDEnzyme-${LLVM_MAJOR_VERSION}.so")
else()
    target_link_options(descriptor PRIVATE "LINKER:--load-pass-plugin=${ENZYME_LIB}/LLDEnzyme-${LLVM_MAJOR_VERSION}.so")
endif()

Compile command:

cmake .. -DENZYME_LIB=/path/to/LLDEnzyme-xx.so
@ipcamit ipcamit changed the title UNREACHABLE executed when function is defined in seperate include file Cannot deduce adding type of: i32 when function is defined in seperate include file Dec 13, 2023
@ipcamit
Copy link
Author

ipcamit commented Dec 13, 2023

Any insights? I revisited it and it seems the error stems from one of the input integer argument, but I do not understand Cannot deduce adding type of: i32 %5 mean?

@ipcamit
Copy link
Author

ipcamit commented Dec 14, 2023

I think I narrowed it down to the fact that in function bessel_basis compiler could not properly identify the size of the array for copying, especially indicated by this line in output:

i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.2, i64 0, i64 0): {[-1]:Pointer, [-1,-1]:Anything}, intvals: {}
@.str.2 = private unnamed_addr constant [49 x i8] c"cannot create std::vector larger than max_size()\00", align 1: {[-1]:Pointer, [-1,-1]:Anything}, intvals: {}
i64 3: {[-1]:Integer}, intvals: {3,}

Therefore I modified the code to assign variable a upper cutoff value NEIGHBOR_MAX. That is, line 82 in Descriptor.cpp became:

number_of_neighbors = (number_of_neighbors > MAX_NEIGHBORS) ? MAX_NEIGHBORS:number_of_neighbors;

and for some reason it has to be like this. Raising exception does not help either.

if (number_of_neighbors > MAX_NEIGHBORS){
 throw std::runtime_error("neigbors out of bound");
}

Also gives the same error. I think this qualifies as a bug. Somehow same behavior is not observed when function is defined in the same file.

@ipcamit
Copy link
Author

ipcamit commented Dec 14, 2023

Also for some reason it is a recurrent problem. Down the line in my library there is another loop using same number_of_neighbors variable

for(int i = 0; i < number_of_neighbors; i++)

I also fails to compile. But with error message:

Enzyme: Cannot deduce type of memset   call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(1) %484, i8 0, i64 %319, i1 false) #70

And googling it yields nothing of importance.

I think it has to do with looping over undefined integer. Because I defined the same loop in 3 formats, one of them compiles successfully, other two fails.

FAILS:

#define MAX_NEIGH=100

for(int i =0; i< number_of_neighbors; i++){
    do something
}

// and

int i = 0;
while((i < number_of_neighbors) && (i < MAX_NEIGH)){
    do something
    ...
}

Compiles:

int i = 0;
while(i < MAX_NEIGH){
    do something
    ...
    i++;
    if (i == number_of_neighbors){
    break;
    }
}

@wsmoses
Copy link
Member

wsmoses commented Dec 17, 2023

Haven't had a chance to look at yet (will try to in near future), but that error message indicate that type analysis cannot determine the type of a variable. You can add looseTypeAnalysis to have it make its best guess, or look at the error message for where it cannot deduce it and add an annotation like __enzyme_double

@ipcamit
Copy link
Author

ipcamit commented Dec 18, 2023

I can confirm that adding -enzyme-loose-types does make the code compile. Will check shortly if it gives same results numerically or not.

Can you please give small example on how to use __enzyme_double? I tried to get clues from the pull request that mentioned it. But I am getting the following error:

/home/amit/Projects/COLABFIT/colabfit-kim-model/dummy-descriptor-library/Descriptors.cpp:87:5: error: use of undeclared identifier '__enzyme_integer'
    __enzyme_integer(&number_of_neighbors,sizeof(int));

What i tried:

void Xi::compute(int index,
                 int number_of_neighbors,
                 double *coordinates,
                 double *desc) {
    __enzyme_integer(&number_of_neighbors,sizeof(int));
 ...

what is the correct way of using __enzyme_integer?

@wsmoses
Copy link
Member

wsmoses commented Feb 13, 2024

hi @ipcamit you have to forward declare the function. Otherwise that looks reasonable.

@ipcamit
Copy link
Author

ipcamit commented Feb 13, 2024

Doh! forward declaration does solve the issue.

@ipcamit ipcamit closed this as completed Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants