mitsuba-renderer / enoki

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

Documentation excludes all initialisation #101

Open superdump opened 4 years ago

superdump commented 4 years ago

The documentation excludes all initialisation which makes it difficult to understand how to start using enoki. Examples of how to make arrays of vectors that are optimally formatted (in terms of data layout) would probably help. It should be reasonable to expect that someone using enoki has used plain C++ T[] arrays, as well as std::vector<T> and perhaps std::array<T> so examples porting from say std::vector<Vector3f> where Vector3f is a plain struct of 3 floats would be informative.

Speierers commented 4 years ago

Hi @superdump,

Enoki arrays are pretty intuitive to initialize. For instance:

using Vector3f = enoki::Array<float, 3>;
Vector3f a(); // -> [0.f, 0.f, 0.f]
Vector3f b(2.f); // -> [2.0, 2.0, 2.0]
Vector3f c(2.f, 3.f, 4.f); // -> [2.0, 3.0, 4.0]

When using enoki::Array<Float, X> where Float is a dynamic type (e.g. DynamicArray or CUDAArray) you can use zero(size), one(size), arange, etc.. to construct vector of arrays (SoA).

You can also have a look at the Mitsuba 2 codebase for inspiration which uses enoki in all its possible forms 😉

If you have a specific problem in mind / snippet of code, I am happy to help for a "translation".

Cheers!

wjakob commented 4 years ago

I think @superdump's request would be to have some auto-translation from standard STL constructs for dynamic arrays, which may be useful to have at some point. My suggestion would be to leave the ticket open and revisit once all the Enoki changes have landed.

wjakob commented 4 years ago

Maybe it's just a documentation issue. In the upcoming Enoki, this would be written as

ek::unravel<Vector3f>(ek::load<Float>(my_std_vector.data(), my_std_vector.size()));
superdump commented 4 years ago

Both responses are useful. That said, if one is using nested arrays with the current enoki release, to leverage packets, so something like:

using FloatP = enoki::array<float, 32>;
using Vector3fP = enoki::array<FloatP, 3>;

Firstly, how do you initialise a single 3-element vector in a Vector3fP? Just the same the Vector3f example by @Speierers above?

Secondly, how do you efficiently use and maintain a contiguous collection of 3-element vectors in a Vector3fP? As in something similar to std::vector<Vector3f> or Vector3f vectors[N] but leveraging the packets. Is there some implicit 'magic' (maybe with allocators? I don't know) that allows you to use a Vector3fP as if it were a single vector of 3 floats and put it into some collection like std::vector? Or do you have to use the enoki dynamic arrays and they handle it all? Do you have to index into the packet members and write code to handle using multiple packets as necessary? (i.e. if you want to store >32 3-element vectors in the Vector3fP then you will need at least two of them.)