mitsuba-renderer / enoki

Enoki: structured vectorization and differentiation on modern processor architectures
Other
1.26k stars 94 forks source link

Link error when trying to use DynamicArray for DiffArray #54

Closed realWDC closed 4 years ago

realWDC commented 4 years ago

I am trying to auto-diff using DiffArray<FloatX> defined below, instead of the usual DiffArray<CudaArray<float>>:

#include <enoki/dynamic.h>
#include <enoki/autodiff.h>

using namespace enoki;

using Float  = float;

// not working:
using FloatP = Packet<Float>;
using FloatX = DynamicArray<FloatP>;
using FloatD = DiffArray<FloatX>;

// working:
// using FloatD = DiffArray<Float>;

int main()
{
    FloatD x = 1.f;
    set_requires_gradient(x);
    FloatD y = 10.f * x;
    backward(y);
    std::cout << y << std::endl;
    std::cout << gradient(x) << std::endl;
}

Compiled with Clang++-9 on Ubuntu 18.04, linked with libenoki-autodiff.so, libenoki-cuda.so and cuda.so (the last two may not need; but just adding FYI). Which gives:

/tests/enoki/CMakeFiles/test_examples.dir/examples.cpp.o: In function `main':
examples.cpp:(.text+0x30): undefined reference to `enoki::Tape<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::get()'
examples.cpp:(.text+0x3f): undefined reference to `enoki::Tape<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::append_leaf(unsigned long)'
examples.cpp:(.text+0x7f): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::mul_(enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > > const&) const'
examples.cpp:(.text+0x89): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::~DiffArray()'
examples.cpp:(.text+0x9a): undefined reference to `enoki::Tape<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::backward(unsigned int, bool)'
examples.cpp:(.text+0x104): undefined reference to `enoki::Tape<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::gradient(unsigned int)'
examples.cpp:(.text+0x166): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::~DiffArray()'
examples.cpp:(.text+0x16e): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::~DiffArray()'
examples.cpp:(.text+0x1cd): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::~DiffArray()'
examples.cpp:(.text+0x1d5): undefined reference to `enoki::DiffArray<enoki::DynamicArray<enoki::Packet<float, 1ul, true, (enoki::RoundingMode)4> > >::~DiffArray()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

If instead using FloatD = DiffArray<Float>;, then it works. How to fix this link error for DiffArray<FloatX> defined above?

wjakob commented 4 years ago

It should be possible to do this with some minor tweaks to the codebase, but it will not be efficient (for the reasons that are described in the documentation section about dynamic CPU arrays). Longer term, I plan to have a JIT compiler for CPU dynamic arrays, at which point it would start to make sense to offer proper support for DiffArray<FloatX>.

realWDC commented 4 years ago

Thank you for the kind reply and future plans.