Search code examples
eigen3

Can eigen supports inconsistent input and output types?


For example, I want to use Eigen to do matrix multiply. But the type of input matrix is int16_t, and the type of output is int32_t. So it causes a compiler error.

Showing Recent Issues /Eigen/src/Core/AssignEvaluator.h:834:3: Static_assert failed due to requirement 'Eigen::internal::has_ReturnType::Scalar, assign_op > >::value' "YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY"

Below is the test code:

#include <iostream>

typedef Eigen::Matrix<int16_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatX16;
typedef Eigen::Matrix<int32_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatX32;


#define MAP_MATRIX(name, ptr, M, N) Eigen::Map<MatX32> name(ptr, M, N)
#define MAP_CONST_MATRIX(name, ptr, M, N) Eigen::Map<const MatX16> name(ptr, M, N)

int main(int argc, const char * argv[]) {

int M, N, K;
M = 10; N = 10; K = 10;
// eigen  int16xint16 = int32
int16_t lhs[100] = {1};
int16_t rhs[100] = {2};
int32_t res[100] = {0};

MAP_CONST_MATRIX(eA, lhs, M, K);
MAP_CONST_MATRIX(eB, rhs, K, N);
MAP_MATRIX(eC, res, M, N);

eC = eA * eB;


return 0;
}

Solution

  • The product of two int16 matrices will be an int16 again. You can cast the result to int32:

    eC = (eA * eB).cast<int32_t>();
    

    However, what you probably actually want, is to cast the original factors to int32. Additionally, you can tell Eigen that eC will not alias with either eA or eB:

    eC.noalias() = eA.cast<int32_t>() * eB.cast<int32_t>();
    

    Note that casting is not vectorized (yet), so you probably get sub-optimal code with this. Your compiler might be smart enough to partially auto-vectorize the product, though.