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

Matrix::row broken with Value=Array<..>? #91

Open
anadodik opened this issue May 20, 2020 · 2 comments
Open

Matrix::row broken with Value=Array<..>? #91

anadodik opened this issue May 20, 2020 · 2 comments

Comments

@anadodik
Copy link

When using Matrix::row with scalars, it works fine. However, using it with a packet, gather produces a compiler error.

Code to reproduce the problem:

using FloatP = enoki::Array<float, 4>;
using Matrix = enoki::Matrix<FloatP, 3>;
spdlog::info("Matrix=\n{}.", matrix.row(0));

Compiler output:

.../ext/enoki/include/enoki/array_router.h:1106:31: error: static assertion failed: gather(): don't know what to do with the input arguments!
 1106 |         static_assert(detail::false_v<Array>, "gather(): don't know what to do with the input arguments!");

I looked through the Enoki codebase, and it seems that the code crashes in a recursive call to array_router.h:gather(), but I am unsure where to go from here.

I am willing to submit a pull request if somebody can point in the right direction? Alternatively, in case it is not planned to change the Matrix::row code in the upstream, or that I am doing something wrong, I am still interested in how this gather call might be performed correctly?

@Speierers
Copy link
Member

IIRC enoki::Matrix is implemented in a way that expects the Value type to be a scalar or a dynamic array (e.g. DynamicArray<FloatP>). You should consider FloatP as an intermediate type which should rarely be used on its own.

In your case, the gather routine isn't implemented on Packet types. Could you use enoki::Matrix<FloatX, 3> instead?

@anadodik
Copy link
Author

Hi, I am trying to rewrite the code using DynamicArray, but this causes a different issue. I've separated a minimal example for reproducing it:

include <doctest/doctest.h>

#include <enoki/array.h>
#include <enoki/matrix.h>
#include <enoki/dynamic.h>

template<typename Value_, size_t Size, typename Value=std::decay_t<Value_>>
enoki::Matrix<Value, Size> does_not_compile(
    const enoki::Matrix<Value_, Size>& in
) {
    return enoki::transpose(in);
}

void example() {
    static constexpr int ArraySize = 2;
    static constexpr int MatSize = 3;

    using Packet = enoki::Packet<float, ArraySize>;
    using ArrayX = enoki::DynamicArray<Packet>;
    using Matrix = enoki::Matrix<ArrayX, MatSize>;

    Matrix enoki_mat;
    enoki::set_slices(enoki_mat, 2);
    enoki::Matrix<Packet&, MatSize> ref = enoki::packet(enoki_mat, 0);
    does_not_compile<Packet&, MatSize>(ref);
}

Changing the signature of transpose in matrix.h into

template <typename Value, size_t Size, bool IsMask_, typename Derived_, typename Derived = enoki::expr_t<Derived_>>
ENOKI_INLINE auto transpose(const StaticArrayBase<Value, Size, IsMask_, Derived_> &a) {

seems to fix the problem. Am I doing something wrong?

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

No branches or pull requests

2 participants